数据结构学习--栈(JAVA代码实现)

什么是栈

栈是一种用于存储数据的简单数据结构(与链表类似)。数据入栈的次序是栈的关键。
栈(stack)是一个有序线性表,只能在表的一端(称为栈顶,top)执行插入和删除操作。最后插入的元素总是被第一个删除。所以,栈也称为后进先出(Last In First Out,FIFO)或者先进后出(First In Last Out,FILO)

栈的抽象数据类型

主要操作

  • void push(int data) :将数据插入栈
  • int pop():删除并返回最后一个插入栈的元素

栈的辅助操作

  • int top():返回最后一个插入栈的元素,但不删除
  • int size():返回存储在栈中的元素的个数
  • int isEmpty():判断栈中是否有元素
  • int isStackFull():判断栈中是否满元素

实现

通过简单数组实现

    /*数组实现栈
    * */
    public class ArrayStack {
        private long[] a;
        private int size;//栈数组的大小
        private int top;//栈顶

        public ArrayStack(int maxSize) {
            this.size = maxSize;
            this.a = new long[size];
            this.top = -1;//表示空栈
        }

        //入栈
        public void push(long value){
            if(isFull()){
                System.out.println("栈已经满!");
                return;
            }
            a[++top] = value;
        }

        //返回栈顶内容,但是不删除
        public void peek(){
            if(isEmpty()){
                System.out.println("栈中没有数据!");
            }
            System.out.println(a[top]);
        }

        //弹出栈顶内容,删除
        public long pop(){
            if(isEmpty()){
                System.out.println("栈中没有数据!");
                return 0;
            }
            return a[top--];
        }

        public int size(){
            return top + 1;
        }

        public boolean isEmpty() {
            return (top == -1);
        }

        public boolean isFull() {
            return (top == size - 1);
        }

        //显示
        public void display(){
            for (long l : a) {
                System.out.println("["+l+"]");
            }
        }
    }

    @Test
    public void testArrayStack(){
        ArrayStack arrayStack = new ArrayStack(3);
        arrayStack.display();
        System.out.println(">>>>1");
        System.out.println(arrayStack.isEmpty());
        System.out.println(arrayStack.isFull());
        System.out.println(">>>>>beforePush");
        arrayStack.push(4);
        arrayStack.push(2);
        arrayStack.push(7);
        arrayStack.display();
        System.out.println(">>>>>afterPush");
        arrayStack.peek();
        arrayStack.pop();
        arrayStack.display();
        System.out.println(arrayStack.isEmpty());
        System.out.println(arrayStack.isFull());
输出结果:
[0]
[0]
[0]
>>>>1
true
false
>>>>>beforePush
[4]
[2]
[7]
>>>>>afterPush
7
[4]
[2]
[7]
false
false

Process finished with exit code 0

    }

动态数组实现

其实具体实现代码和上面一样,加多一条动态扩展数组功能

        public void doubleArray(){
            long newArray[] = new long[size*2];
            System.arraycopy(a,0,newArray,0,size);
            size = size * 2;
            a = newArray;
        }

只需在栈满时候,调用上面的方法即可。

链表实现

在这里插入图片描述


   /*链表*/
    public class LLNode {
        private int data;//存放数据
        private LLNode next;//指向下一个节点

        public LLNode() {
        }

        public LLNode(int data) {
            this.data = data;
        }

        public int getData() {
            return data;
        }

        public void setData(int data) {
            this.data = data;
        }

        public LLNode getNext() {
            return next;
        }

        public void setNext(LLNode next) {
            this.next = next;
        }
    }

    /*链表实现的栈*/
    public class LLStack{
        LLNode headnode = null;

        public LLStack() {
            headnode = new LLNode();//初始化栈
        }

        public boolean isEmpty(){
            return headnode ==null;
        }

        public void push(int data) {
            if (isEmpty()){
                headnode = new LLNode(data);
            }else {
                LLNode llNode = new LLNode(data);
                llNode.setNext(headnode);
                headnode = llNode;
            }
        }

        public int pop(){
            if(isEmpty()){
                System.out.println("栈为空");
                return 0;
            }
            int data = headnode.getData();
            headnode = headnode.getNext();
            return data;
        }

        public int top(){
            if(isEmpty()){
                System.out.println("栈为空");
                return 0;
            }
            int data = headnode.getData();
            return data;
        }

        public int length(){
            int count = 0;
            LLNode temp = headnode;
            if(isEmpty()){
                return count;
            }else {
                while (temp!=null){
                    count++;
                    temp = temp.getNext();
                }
                count++;
                return count;
            }
        }
    }

栈的三种实现方法的比较

基于数组实现的

  1. 各个操作都是常数时间的开销
  2. 每隔一段时间倍增操作的开销较大
  3. (从空栈开始)n个操作的任意序列的平摊时间开销为O(n)

基于链表实现的

  1. 栈规模的增加减小都很简洁
  2. 各个操作都是常数时间的开销
  3. 每个操作都是要使用额外的空间和时间来处理指针

本人学习的理解笔记,如有错误!不吝赐教,请留言,谢谢你!

猜你喜欢

转载自blog.csdn.net/weixin_42553616/article/details/106765343