Java数据结构:栈

3. 栈(stack)

3.1 简介

栈只允许在有序的线性数据集合的一端(栈顶top)进行加入数据(push)和移除数据(pop)。

  • 栈只能在栈顶进行push和pop操作。
  • 后进先出(LIFO,Last In First Out)
  • 常用一维数组或链表实现:
    • 顺序栈:数组实现
    • 链式栈:链表实现
  • 执行复杂度:
    • 访问:O(n),访问栈底(bottom)元素时
    • 插入删除:O(1),只允许在顶端插入和删除

3.2 常见应用

处理只在一段插入和删除数据,并满足先进后出的特性

3.2.1 浏览器的回退和前进

使用两个栈实现。回退时将stack1的栈顶移入stack2中,前进时将stack2的栈顶返回stack1中

img

参考资料

3.3.2 检查符号是否成对出现

给定一个只包括 '('')''{''}''['']' 的字符串,判断该字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

比如 "()"、"()[]{}"、"{[]}" 都是有效字符串,而 "(]" 、"([)]" 则不是

public static boolean isValid(String s){
    // 括号之间的对应规则
    HashMap<Character, Character> mappings = new HashMap<Character, Character>();
    mappings.put(')', '(');//右符号是key,左符号是value
    mappings.put('}', '{');
    mappings.put(']', '[');
    Stack<Character> stack = new Stack<Character>();
    char[] chars = s.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        //跳过其他字符
        if(!mappings.containsKey(chars[i]) && !mappings.containsValue(chars[i])){
            continue;
        }
        if (mappings.containsKey(chars[i])) {
            //stack.pop()的返回值为弹出的栈顶
            char topElement = stack.empty() ? '#' : stack.pop();
            if (topElement != mappings.get(chars[i])) {
                return false;
            }
        } else {
            stack.push(chars[i]);
        }
    }
    return stack.isEmpty();
}

3.2.3 反转字符串

栈中每个元素先入栈再出栈

3.2.4 维护函数调用

最后一个被调用的函数必须先完成执行,符合后进先出特性

3.3 栈的实现

该代码省去了确保容量大小和扩容的部分,在实例化对象时可以选择使用默认的大小或者自己设置容量大小。

 //数组法
public class MyStack {
    private int[] storage;//存放栈中元素的数组
    private int capacity;//栈的容量
    private int count;//栈中元素的数量
    //private static final int GRO_FACTOR = 2;//扩容因子

    //无初始容量,无参构造器
    public MyStack() {
        this.capacity = 8;
        this.storage = new int[capacity];
        this.count = 0;
    }

    //设定初始容量
    public MyStack(int capacity) {
        if(capacity<1){
            throw new IllegalArgumentException("Capacity is too small");
        }
        this.capacity = capacity;
        this.storage = new int[capacity];
        this.count = 0;
    }

    //入栈
    public void push(int value){
        storage[count++] = value;
    }

    //确保容量大小
    //扩容

    //返回栈顶元素并出栈
    public int pop(){
        if(count==0){
            throw new IllegalArgumentException("Stack is empty");
    }
        count--;
        return storage[count];
    }

    //返回栈顶元素不出栈
    public int peek(){
        //return storage[count];//写错
        return storage[count-1];
    }

    //判断栈是否为空
    public boolean isEmpty(){
        return count == 0;
    }

    //返回元素个数
    public int size(){
        return count;
    }
}
posted @ 2022-03-22 16:20  chachan53  阅读(89)  评论(0编辑  收藏  举报