数据结构-栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

自己实现栈:

复制代码
public int push(int e) {
}
public int pop(){
}
public int peek(){    
}
public int size(){  
}
public boolean empty(){
  
}

用数组实现一个栈,这个类的成员变量为数组,和整数变量,用来记录栈中的元素个数。

1,push:如果数组满了,需要进行扩容

复制代码
private boolean isFull(){
    return size==array.length;
}
private void expansionArray(){
    array= Arrays.copyOf(array,array.length*2);
}
public int push(int val){
    if (isFull()){
        expansionArray();
    }
    array[size]=val;
    size++;
    return val;
}

2,pop:要取出栈顶元素,也就是数组的最后一个元素

复制代码
public int pop(){
    int tmp=peek();
    size--;
    return tmp;

}

3,peek:看一看栈顶元素

复制代码
public int peek(){
    if (empty()){
        throw new RuntimeException();
    }
    return array[size-1];
}

4,size/empty:

复制代码
public int size(){
    return size;
}
public boolean empty(){
    return size==0;

}

练习:

1,逆波兰表达式求值;

大致思路:

遍历字符串,当遇到数字时,将数字入栈,碰到运算符时,弹出两个栈顶元素,通过该运算符进行计算后,再将结果入栈,之后继续进行遍历,重复上述步骤。最后栈顶元素就是最终结果

复制代码
public static int evalRPN(String[] tokens){
    Stack<Integer> stack=new Stack<>();
    for (int i = 0; i < tokens.length; i++) {
        if(!isOperation(tokens[i])){
            Integer val=Integer.valueOf(tokens[i]);
            stack.push(val);
        }else {
            String ret=tokens[i];
            int s2= stack.pop();
            int s1= stack.pop();
            switch (ret){
                case "+":
                    stack.push(s1+s2);
                    break;
                case "-":
                    stack.push(s1-s2);
                    break;
                case "*":
                    stack.push(s1*s2);
                    break;
                case "/":
                    stack.push(s1/s2);
                    break;

            }
        }
    }
    return stack.pop();
}

2,括号是否匹配

给一个括号的式子,看式子中的括号是否相互匹配

遍历字符串,遇到 ' ( ' , ' [ ' , ' { ' .时,入栈。如果遇到 ' ) ' , ' ] ' , ' } '.则弹出栈顶元素,并看栈顶元素和遇到的元素是否匹配。如果最后栈元素为空,则说明括号匹配成功

复制代码
private static boolean isOperation(String ret){
     if(ret=="+"||ret=="-"||ret=="*"||ret=="/"){
         return true;
     }
     return false;
 }
//判断括号是否匹配
public static boolean isValid(String s){
    Stack<Character> stack=new Stack<>();
    for (int i = 0; i <s.length(); i++) {
        char ret=s.charAt(i);
        if (ret=='('||ret=='['||ret=='{'){
            stack.push(ret);
        }
        else {
            if (stack.isEmpty()){
                return false;
            }else {
                char ch2=stack.peek();
                if (ch2=='('&&ret==')'||ch2=='['&&ret==']'||ch2=='{'&&ret=='}'){
                    stack.pop();
                }
            }
        }
    }
    return stack.isEmpty();
}

3,给出两个整数数组,看第二个数组是否是第一个数组以不同方式出栈的一种结果。

遍历第一个数组,并将每一个元素放到栈中,直到栈顶元素与第二个数组的元素相同,弹出栈顶元素,并且第二个数组向后遍历,并判断栈顶元素是否与第二个数组的元素是否相同,如果相同,重复上一步骤。如果不相同继续放入数组一的元素。如果遍历完第二个数组,且栈中的元素为0,则数组二是数组一出栈的一种方式

复制代码
public static boolean isPopOrder(int []pushV,int [] popV){
    Stack<Integer> stack=new Stack<>();
    int j=0;
    for (int i = 0; i < pushV.length; i++) {
        stack.push(pushV[i]);
        while (!stack.isEmpty()&&stack.peek()==popV[j]&&j<popV.length){
                stack.pop();
                j++;
        }
    }
    return stack.isEmpty();
}

**4,创立一个类,得到最小值。**类中有两个栈,一个正常放入元素,另一个的栈顶元素为第一个栈中的最小值

复制代码
public class MinStack {
    Stack<Integer> stack;
    Stack<Integer> minStack;

    public MinStack(Stack<Integer> stack, Stack<Integer> minStack) {
        this.stack = new Stack<>();
        this.minStack = new Stack<>();
    }
}

(1)push:如果minStack为空,在stack,minStack中均放入该元素。如果放入的元素大于minStack的栈顶元素,则不放入minStack,如果放入的元素小于minStack栈顶元素,则将该元素放入minStack

复制代码
public void push(int val){
   if (minStack.isEmpty()){
       stack.push(val);
       minStack.push(val);
   }else {
       if (minStack.peek()>val){
           minStack.push(val);
       }
       stack.push(val);
   }
}

(2)pop:弹出stack的栈顶元素,如果stack的栈顶元素与minStack的栈顶元素相同,则minStack也弹出栈顶元素。

复制代码
public void pop(){
    if (stack.isEmpty()){
        return;
    }
    if (stack.peek()==minStack.peek()){
        minStack.pop();
        stack.pop();
    }else {
        stack.pop();
    }

}

(3)top:打印stack的栈顶元素

复制代码
public int top(){
    if (stack.isEmpty()){
        return -1;
    }
    return stack.peek();
}

(4)getMin:打印stack中的最小值,也就是minStack的栈顶元素

复制代码
public int getMin(){
    if (stack.isEmpty()){
        return -1;
    }
    return minStack.peek();
}
相关推荐
Amd7943 小时前
深入探讨索引的创建与删除:提升数据库查询效率的关键技术
数据结构·sql·数据库管理·索引·性能提升·查询优化·数据检索
OKkankan8 小时前
实现二叉树_堆
c语言·数据结构·c++·算法
指尖下的技术9 小时前
Mysql面试题----为什么B+树比B树更适合实现数据库索引
数据结构·数据库·b树·mysql
Bunury12 小时前
组件封装-List
javascript·数据结构·list
Joeysoda12 小时前
Java数据结构 (从0构建链表(LinkedList))
java·linux·开发语言·数据结构·windows·链表·1024程序员节
比特在路上12 小时前
ListOJ14:环形链表II(寻找环的入口点)
数据结构·链表
涅槃寂雨16 小时前
C语言小任务——寻找水仙花数
c语言·数据结构·算法
『往事』&白驹过隙;16 小时前
操作系统(Linux Kernel 0.11&Linux Kernel 0.12)解读整理——内核初始化(main & init)之缓冲区的管理
linux·c语言·数据结构·物联网·操作系统
就爱学编程16 小时前
从C语言看数据结构和算法:复杂度决定性能
c语言·数据结构·算法
半桔16 小时前
栈和队列(C语言)
c语言·开发语言·数据结构·c++·git