Java data structures and algorithms Stack Series ---

table of Contents

1, the basic concept of the stack 2, Java stack implementation simple sequential simulated 3, 4 enhancements stack version, implemented using a string in reverse stack 5, the stack is determined by using the separator 6 matches summary

1, the basic concept of the stack

Stack (English: stack), also known as a stack or stack, the stack as a data structure, only a specific linear table insertion and deletion operations at one end. It stores data in accordance with the principle of last-out, first enter the data is pushed onto the stack at the end, the final data in the top of the stack, when you need to read data starts pop-up data (the last data is first read out) from the top of the stack. Stack having a memory effect, insertion and deletion of stack operation, it is unnecessary to change the bottom of the stack pointer. Stack is allowed to insert special linear form and delete operations at the same end. It allows for insertion and deletion of one end called stack (Top), and the other end of the stack bottom (bottom); fixed bottom of the stack, the stack while floating; called an empty stack if the number of elements in the stack is zero. Commonly referred to insert into the stack (PUSH), delete is called the stack back (POP). Since the stack data structure may only be performed at one end, and thus in accordance with LIFO (LIFO, Last In First Out) principle of operation. Stack also known as LIFO table. Here badminton tube, for example, a stack badminton tube is beginning badminton cartridge is empty, the stack is empty, then one by one we put in badminton, a push is a push, when we need to use badminton, from there take the tube, that is, pop pop, but first get into badminton is our last go.

2, Java simulate simple sequential stack implementation

package com.ys.datastructure;
public class MyStack {
    private int[] array;
    private int maxSize;
    private int top;
     
    public MyStack(int size){
        this.maxSize = size;
        array = new int[size];
        top = -1;
    }
     
    //压入数据
    public void push(int value){
        if(top < maxSize-1){
            array[++top] = value;
        }
    }
     
    //弹出栈顶数据
    public int pop(){
        return array[top--];
    }
     
    //访问栈顶数据
    public int peek(){
        return array[top];
    }
     
    //判断栈是否为空
    public boolean isEmpty(){
        return (top == -1);
    }
     
    //判断栈是否满了
    public boolean isFull(){
        return (top == maxSize-1);
    }
}
复制代码

test:

package com.ys.test;
 
import com.ys.datastructure.MyStack;
 
public class MyStackTest {
    public static void main(String[] args) {
        MyStack stack = new MyStack(3);
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack.peek());
        while(!stack.isEmpty()){
            System.out.println(stack.pop());
        }         
    } 
}
复制代码

result:

The stack is implemented in an array, it defines an internal array, represents a maximum capacity value of the variable and a top point of the top element. The constructor creates a new predetermined capacity parameter stack, Push () is pressed into the stack elements, points to the top of top plus a variable to point to a position above the original data item to the top, and in this position a data storage. pop () method returns the variable points of the top element, the top and Save a variable, the data items will be removed. To know the top is always an element of variable points to the top of the stack.

Problems arising from:

①, after initial capacity to achieve the above stack, it can not be followed by expansion (although not the stack is used to store large amounts of data), how to do after if the latter exceeds the initial amount of data capacity? (Automatic expansion)

②, we implemented an array of stacks in defined array type when it specifies the type of data stored on the stack, then the same stack can store different types of data it? (Declared as Object)

③, the stack needs to be initialized capacity, and achieve the stack elements of the array are stored contiguously, so capacity can not fail to initialize it? (Change implemented by list)

3, enhanced version stack function

For the problems above, the first expansion automatically, and the second can store different types of data, the solution is as follows :( third in the list when talking about the introduction)

The simulation of the stack in the JDK source code, you can refer to implement Stack class.

package com.ys.datastructure;
import java.util.Arrays;
import java.util.EmptyStackException;
 
public class ArrayStack {
    //存储元素的数组,声明为Object类型能存储任意类型的数据
    private Object[] elementData;
    //指向栈顶的指针
    private int top;
    //栈的总容量
    private int size;
     
     
    //默认构造一个容量为10的栈
    public ArrayStack(){
        this.elementData = new Object[10];
        this.top = -1;
        this.size = 10;
    }
     
    public ArrayStack(int initialCapacity){
        if(initialCapacity < 0){
            throw new IllegalArgumentException("栈初始容量不能小于0: "+initialCapacity);
        }
        this.elementData = new Object[initialCapacity];
        this.top = -1;
        this.size = initialCapacity;
    }
     
     
    //压入元素
    public Object push(Object item){
        //是否需要扩容
        isGrow(top+1);
        elementData[++top] = item;
        return item;
    }
     
    //弹出栈顶元素
    public Object pop(){
        Object obj = peek();
        remove(top);
        return obj;
    }
     
    //获取栈顶元素
    public Object peek(){
        if(top == -1){
            throw new EmptyStackException();
        }
        return elementData[top];
    }
    //判断栈是否为空
    public boolean isEmpty(){
        return (top == -1);
    }
     
    //删除栈顶元素
    public void remove(int top){
        //栈顶元素置为null
        elementData[top] = null;
        this.top--;
    }
     
    /**
     * 是否需要扩容,如果需要,则扩大一倍并返回true,不需要则返回false
     * @param minCapacity
     * @return
     */
    public boolean isGrow(int minCapacity){
        int oldCapacity = size;
        //如果当前元素压入栈之后总容量大于前面定义的容量,则需要扩容
        if(minCapacity >= oldCapacity){
            //定义扩大之后栈的总容量
            int newCapacity = 0;
            //栈容量扩大两倍(左移一位)看是否超过int类型所表示的最大范围
            if((oldCapacity<<1) - Integer.MAX_VALUE >0){
                newCapacity = Integer.MAX_VALUE;
            }else{
                newCapacity = (oldCapacity<<1);//左移一位,相当于*2
            }
            this.size = newCapacity;
            int[] newArray = new int[size];
            elementData = Arrays.copyOf(elementData, size);
            return true;
        }else{
            return false;
        }
    }           
}
复制代码

test:

//测试自定义栈类 ArrayStack
//创建容量为3的栈,然后添加4个元素,3个int,1个String.
@Test
public void testArrayStack(){
    ArrayStack stack = new ArrayStack(3);
    stack.push(1);
    //System.out.println(stack.peek());
    stack.push(2);
    stack.push(3);
    stack.push("abc");
    System.out.println(stack.peek());
    stack.pop();
    stack.pop();
    stack.pop();
    System.out.println(stack.peek());
}
复制代码

result:

4, implemented using a stack string in reverse

We know that the stack is LIFO, we can be divided into a single string of characters, a character and then a push () into the stack, in a a pop () is out of the stack in reverse order shows. as follows:

The string "how are you" reverse! ! !

ps: Here we use the above custom stack to achieve, you can try to replace the ArrayStack comes with the JDK class stack Stack

//进行字符串反转
@Test
public void testStringReversal(){
    ArrayStack stack = new ArrayStack();
    String str = "how are you";
    char[] cha = str.toCharArray();
    for(char c : cha){
        stack.push(c);
    }
    while(!stack.isEmpty()){
        System.out.print(stack.pop());
    }
}
复制代码

result:

5, the stack is determined by using delimiter matches

Wrote xml tag or html tags, we all know <must Recent> match, [must and recent] to match. For example: This is a symbol to match, if it is abc] that do not match. For the 12, we analyze the data in the stack: encountered match the correct eliminated

Contents of the last stack is empty match succeeds, otherwise fails to match! ! !

//分隔符匹配
//遇到左边分隔符了就push进栈,遇到右边分隔符了就pop出栈,看出栈的分隔符是否和这个有分隔符匹配
@Test
public void testMatch(){
    ArrayStack stack = new ArrayStack(3);
    String str = "12";
    char[] cha = str.toCharArray();
    for(char c : cha){
        switch (c) {
        case '{':
        case '[':
        case '<':
            stack.push(c);
            break;
        case '}':
        case ']':
        case '>':
            if(!stack.isEmpty()){
                char ch = stack.pop().toString().toCharArray()[0];
                if(c=='}' && ch != '{'
                    || c==']' && ch != '['
                    || c==')' && ch != '('){
                    System.out.println("Error:"+ch+"-"+c);
                }
            }
            break;
        default:
            break;
        }
    }
}
复制代码

6, summed up

According to LIFO stack features, we realized the reverse order of words and delimiters match. So in fact the stack is a conceptual tool, to achieve what specific function can imagine by us. By providing a stack method of limiting access push () and pop (), so that the program is not prone to error. For achieving the stack, little analysis we know, the data is pushed and popped are time complexity O (1), that is to say the consumption of time of stack operation does not depend on the number of data items in the stack, and therefore the operation time very short. Also to be noted that the comparison does not need to stack and move operations, we do not superfluous.

Guess you like

Origin juejin.im/post/5def9dbaf265da33d912d357
Recommended