栈及栈的应用案例

概述

生活中的栈  客栈

计算机中的栈

我们把生活中的栈的概念引入到计算机中,就是供数据休息的地方它是一种数据结构,数据既可以进入到栈中,又可以从栈中出

去。

栈是一种基于先进后出(FILO)的教据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储教据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来 )。我们称数据进入到栈的动作为压栈,数据从栈中出去的动作为弹栈。

栈的实现

我们采用链表来实现栈结构

方法:栈是否为空 isEmpty()、获取栈中的元素个数size()、弹栈pop() 、压栈 push、遍历

因为需要使用链表来实现,所以 需要head节点和Node节点类

Java里面有对应的实现Stack类

package com.d318;
import java.util.EmptyStackException;
public class Stack {
    private Node head;
    private int count;
    // 构造方法的创建
    public Stack() {
        this.head = new Node(null, null);
        this.count = 0;
    }
    // 获取栈中元素个数
    public int size() {
        return count;
    }
    // 获取栈是否为空
    public boolean isEmpty() {
        return count == 0;
    }
    // 入栈
    public void push(String data) {
        Node newNode = new Node(data, null);
        Node next = head.next;
        head.next = newNode;
        newNode.next = next;
        count++;
    }
    // 弹栈  按照FILO原则,先进的后出,后进的先出
    public String pop() {
        if (count == 0)
            throw new EmptyStackException();
        Node target = head.next;
        Node next = target.next;
        head.next = next;
        count--;
        return target.data;
    }
    public void printStack(){
        Node cur = head.next;
        while(cur!=null){
            System.out.println(cur.data);
            cur = cur.next;
        }
    }
    public static void main(String[] args) {
        Stack stack = new Stack();
        stack.push("aaa");
        stack.push("bbb");
        stack.push("ccc");
        stack.push("ddd");
        stack.push("eee");
        stack.push("fff");
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.isEmpty());
        System.out.println(stack.size());
        stack.printStack();
    }
}
class Node {
    public String data;
    public Node next;
    public Node(String data, Node next) {
        this.data = data;
        this.next = next;
    }
}
栈的应用案例
括号匹配问题

问题描述:

给定一个字符串,里边可能包含”()“小括号和其他字符,请编写程序检查该字符串的中的小括号是否成对出现

例如 :

(上海)(长安): 正确匹配

上海((长安)): 正确匹配

上海(长安(北京)(深圳)南京):正确匹配

上海(长安)): 错误匹配

((上海)长安: 错误匹配

思路:遇到左括号就入栈,遇到右括号就将栈里的左括号弹出与之匹配;

如果遇到右括号,栈中没有与之匹配的左括号,则说明括号不匹配;

如果遍历完了整个字符串,也就是没有右括号了,但是此时栈中还有左括号等待被匹配,那就说明左括号数量大于右括号数量,括号数量也不匹配;

如果遍历完整个字符串,栈中也没有左括号等待被匹配,此时正好匹配;

public static boolean isMatch(String str) {
        Stack stack = new Stack(); // 创建栈对象,这里使用了String类型,而非默认的Object
        for (int i = 0; i < str.length(); i++) { // 这里原代码中的'日'应该为'0'
            char c = str.charAt(i);
            if (c == '(') {
                // 遇见左括号就压入栈中
                stack.push("" + c); // 此处直接将字符转为字符串入栈,也可以省略+""
            } else if (c == ')') { // 漏掉了else if,来确保仅对右括号处理
                // 遇见右括号就将栈中的左括号弹出与之匹配
                if (stack.isEmpty()) {
                    return false; // 栈为空,说明右括号数量大于左括号数量
                }
                stack.pop(); // 弹出栈顶元素
            }
        }
        // 字符串遍历完,检查栈中是否还有剩余左括号
        if (!stack.isEmpty()) {
            return false; // 栈中仍有左括号,说明左括号数量大于右括号数量
        }
        return true; // 栈为空,表示所有括号都已正确匹配
    }

逆波兰表达式求值问题

计算中缀表达式 3*(17-15)+18/6的逆波兰表达式的结果值

思路:遍历数组,如果元素是数据,直接入栈,是符号就从栈中弹出两个值进行计算,计算完后的结果入栈,遍历完数组之后就将最后的结果弹栈

代码:

package com.d318;


public class ReversePoLoTest {
    public static void main(String[] args) {
        //  计算中缀表达式 3*(17-15)+18/6的逆波兰表达式的结果值
        String[] notation = {"3", "17", "15", "-", "*", "18", "6", "/", "+"};
        int result = caculate(notation);
        System.out.println(result);
    }

    public static int caculate(String[] notation) {
        Stack stack = new Stack();
        for (String s : notation) {
            // 如果s是数据,直接入栈,是符号就从栈中弹出两个值进行计算,计算完后的结果入栈
            int a, b,result;
            switch (s) {
                case "+":
                    a = Integer.valueOf(stack.pop());
                    b = Integer.valueOf(stack.pop());
                    result = a+b;
                    stack.push(result + "");
                    break;
                case "-":
                    a = Integer.valueOf(stack.pop());
                    b = Integer.valueOf(stack.pop());
                    result = b-a;
                    stack.push(result + "");
                    break;
                case "*":
                    a = Integer.valueOf(stack.pop());
                    b = Integer.valueOf(stack.pop());
                    result = a*b;
                    stack.push(result + "");
                    break;
                case "/":
                    a = Integer.valueOf(stack.pop());
                    b = Integer.valueOf(stack.pop());
                    result = b/a;
                    stack.push(result + "");
                    break;
                default:
                    stack.push(s);
                    break;
            }
        }
        return Integer.valueOf(stack.pop());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值