Java data structure | stack and its application

Table of contents

1. Stack

Second, the simulation implementation of the stack

Three, the application of the stack


1. Stack

Stack : A special linear list that only allows insertion and deletion of elements at a fixed end . The end where data insertion and deletion operations are performed is called the top of the stack, and the other end is called the bottom of the stack. The data elements in the stack follow the principle of LIFO (Last In First Out).

Top of the stack (Top): The end of the linear table that allows insertion and deletion. Bottom of the stack (Bottom): Fixed, the other end that does not allow insertion and deletion. Empty stack : An empty list without any elements.

  • stack usage

method Features
Stack() construct an empty stack
And push(And e) Push e onto the stack and return e
And pop() Pop the top element of the stack and return
E peek() Get the top element of the stack
int size() Get the number of valid elements in the stack
boolean empty() Check if the stack is empty

According to the underlying code of the stack, it can be known. The bottom layer of the stack is implemented using an array

Stack in the Java collection framework inherits from Vector

  • Since Vector has 4 constructors, plus one of Stack itself, that is to say, there are 5 ways to create Stack

  • Like Vector, it is a stack that can be implemented by an array .

Then you can use an array to simply simulate a stack

Second, the simulation implementation of the stack

Then you can use an array to simply simulate a stack

  • Simulation implementation of the stack

    • Initialize the stack

    public class MyStack {
        public int elem[];
    ​
        public int usedsize;
    ​
        //设置一个默认的大小
        public static final int DEFAULT_SIZE = 10;
    ​
        public MyStack(){
            this.elem = new int[DEFAULT_SIZE];
        }
    • Implementation of stack push

     public int push(int val){
         //将val压入栈,并返回val,判断栈是否为满,如栈满则进行扩容
            if(isFull()){
                elem = Arrays.copyOf(elem,2*elem.length);
            }
         //使用数组实现栈时,栈顶元素的下标即usedsize-1,在usedsize下标处新增元素即可
            this.elem[usedsize] = val;
            usedsize++;
            return val;
        }
    • Achievement

    public boolean isFull(){
            return usedsize == elem.length;
        //如果usedsize等于数组的长度则满
      }
    • Elements are popped

     public int pop(){
           if(isEmpty()){
               throw new StackEmptyException("此时栈为空");
           }
         //先将usedsize--再返回
           return elem[--usedsize];
     }
    • Realization of null judgment

    public boolean isEmpty(){
            return usedsize == 0;
    }
    //自定义异常
    public class StackEmptyException extends RuntimeException{
        public StackEmptyException() {
        }
        public StackEmptyException(String message) {
            super(message);
        }
    }
    • Get the top element of the stack (only get without changing the position)

    public int peek(){
           if(isEmpty()){
               throw new StackEmptyException("此时栈为空");
           }
           return elem[usedsize-1];
    }
    • test

    public class TestStack {
        public static void main(String[] args) {
            MyStack stack = new MyStack();
            stack.push(1);
            stack.push(2);
            stack.push(3);
            stack.push(4);
            stack.push(5);
            stack.push(6);
            System.out.println(stack.peek());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
        }
    }

     

Three, the application of the stack

  • change the sequence of elements

If the push sequence is 1, 2, 3, 4, and the stack can be popped during the push process, then the following impossible pop sequence is ()

A: 1,4,3,2 B: 2,3,4,1 C: 3,1,4,2 D: 3,4,2,1

According to the nature of the stack first-in-last-out, combined with the process of stacking in the question, the stack can also be popped out, such as option A: 1 in 1 out, 2 in 3 in 4 in, 4 out 3 out 2 out is in line with the meaning of the question, the same reason In option C, it is impossible to directly output 1 after 1 in, 2 in, 3 in and 3 out, so option C is impossible to realize.

The initial state of a stack is empty. Now put the elements 1, 2, 3, 4, 5, A, B, C, D, E into the stack in sequence, and then pop them out in sequence, the order of the elements popping out is ( )

A: 12345ABCDE B: EDCBA54321 C: ABCDE12345 D: 54321EDCBA

First in last out, push into the stack in turn, and pop out of the stack in turn, so option B is reasonable

  • Reverse Polish expression evaluation (postfix-expression)

Reverse Polish expression is a kind of suffix expression, the so-called suffix is ​​that the indicator is written after.

The commonly used formula is an infix expression, such as ( 1 + 2 ) * ( 3 + 4 ). The reverse Polish expression of this formula is ( ( 1 2 + ) ( 3 4 + ) * ).

The suffix expression of (a+b)*c-(a+b)/e is:

(a+b)*c-(a+b)/e

→((a+b)*c)((a+b)/e)-

→((a+b)c*)((a+b)e/)-

→(ab+c*)(ab+e/)-

→ab+c*ab+e/-

Idea: Construct a function to judge the operator, and then push it to the stack if it is judged as a number. When encountering an operator, pop two elements to perform related operations, and push the result of the operation to the stack again until the last element is popped off the stack. the result of.

( ( 1 2 + ) ( 3 4 + ) * )

1, 2 are pushed into the stack first, and when operator + is encountered, they are popped out, 3 is added to the stack when 1, 2 is added, 7 is pushed into the stack in the same way as 3, 4, and *, 3, 7 are popped and multiplied at the end. twenty one

Code:

  public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
      //字符数组进行遍历
        for(String x : tokens){
            if(!isOperation(x)){
                //使用parseInt()函数将字符串转换为整型
                stack.push(Integer.parseInt(x));
            }else{
                //如果遇到运算符,弹出数据进行相关操作
                int num2 = stack.pop();
                int num1  = stack.pop();
                switch(x){
                    case "+":
                        stack.push(num1+num2);
                        break;
                    case "-":
                        stack.push(num1 - num2);
                        break;
                    case "*":
                         stack.push(num1*num2);
                         break;
                    case "/":
                        stack.push(num1 / num2);
                        break;
                }
            }
        }
        return stack.pop();
    }
//判断是否为运算符
    private boolean isOperation(String s){
        if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")){
            return true;
        }else{
            return false;
        }
    }
  • Turn recursion into loop

Such as: print the linked list in reverse order

Recursive printing in reverse order

 public void display(ListNode head){
        if(head == null){
            return;
        }
     //直到链表末尾,再归回去
        if(head.next == null){
            System.out.println(head.val+" ");
            return;
        }
        display(head.next);
        System.out.println(head.val+" ");
}

Printing in reverse order using a stack

public void display(ListNode head){
        if(head == null){
            return;
         }
        Stack<ListNode> stack  = new Stack<>();
        ListNode cur = head;
         while(cur!= null){
              stack.push(cur);
              cur = cur.next;
             }
        while(!stack.empty()){
            ListNode ret =   stack.pop();
            System.out.println(ret.val+" ");
        }
    }

Using the first-in-last-out feature of the stack, all the nodes of the linked list are added to the stack, and then popped out of the stack one by one, and the value of val of the nodes in the stack is printed, that is, the reverse order printing of the linked list is realized.

ced485cbb11e458d81a746890b32cf3f.gif

Guess you like

Origin blog.csdn.net/m0_56361048/article/details/127171588