回顾总结之数据结构:4 栈

栈是一种先进后出的有序列表。限制元素的插入和删除只能在同一端,也即栈顶,另一端为固定的一端,被称为栈底。本文主要是介绍栈的数组实现和链表实现。

1 数组实现

使用数组实现,首先需要一个数组来存储数据,并用 maxSize 来表示该数组的大小,然后使用 top 来表示当前位于栈顶的元素的下标,当进行弹出或入栈操作的时候,就是对 top 以及它对应的元素进行处理,初始化的时候 top=-1,表示栈空。
思路比较简单,就直接上代码了。

package com.datastructure.stack;

public class ArrayStack implements MyStack {
    
    
    private int maxSize; //栈容量
    private int[] stack; //存放栈元素
    private int top;  //栈顶元素的下标

    public ArrayStack(int maxSize) {
    
    
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
        top = -1;  //栈空时 top = -1
    }

    public boolean isFull() {
    
    
        return top == maxSize - 1;  //数组满了就是栈满了
    }

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

    //push的时候先确定栈没有满
    //然后top+1,并将新元素存放到该下标处
    public void push (int value) {
    
    
        if(isFull()) {
    
    
            System.out.println("栈空间已满");
            return;
        }
        top++;
        stack[top] = value;
    }

    //先返回当前top所指的元素
    //然后top-1,指向新的top元素所在位置
    public int pop() {
    
    
        if(isEmpty()) {
    
    
            System.out.println("栈空");
            throw new RuntimeException("栈空,无法弹出数据");
        }
        return stack[top--];
    }

    public void show() {
    
    
        if(isEmpty()) {
    
    
            System.out.println("栈空");
            return;
        }
        for(int i=top; i>-1; --i) {
    
    
            System.out.printf("stack[%d]=%d\n",i,stack[i]);
        }
    }
}

2 单向链表实现

将每个栈元素用数据节点表示,一个简单栈节点必须要 value 来存储值,next 来存储下一个元素。

class StackNode {
    
    
    int value; //值
    StackNode next; //指向下一个节点
    StackNode(int value) {
    
    
        this.value = value;
        this.next = null;
    }
}

唯一需要理清的一点就是,top 该对应链表中的哪个节点?这得看看 top 需要满足什么条件:

  • 频繁的插入、删除,因此也需要快速访问到该节点;
  • 从 top 节点能轻易的访问到随后的节点。

对于单向链表,在任意位置插入、删除所作的操作都是一样的,但访问速度却不一样,链表头部的节点访问速度显然更快。对于第二个条件,也是头节点才能满足。
所以我们使用一个带头节点的单向链表来实现栈,top 就是头节点,栈顶节点是 top.nexttop.next == null 时表示栈为空,这里假设栈不会满,当然也是可以设置栈大小的。

package com.datastructure.stack;

public class LinkedStack implements MyStack{
    
    
    StackNode top;//top是正真top节点的前一个节点,类似于头节点
    LinkedStack() {
    
    
        top = new StackNode(-1);
    }
    //入栈
    //将新节点插入到头节点后面
    @Override
    public void push(int value) {
    
    
        if (isFull()) {
    
    
            System.out.println("栈满");
            return;
        }
        StackNode newNode = new StackNode(value);
        newNode.next = top.next;
        top.next = newNode;
        System.out.println("新增元素:" + value);
    }

    //出栈
    //将 top.next 指向原 top.next 的后一个节点
    @Override
    public int pop() {
    
    
        if (isEmpty()){
    
    
            System.out.println("栈空");
            throw new RuntimeException("栈空,无法弹出");
        }
        int value = top.next.value;
        top.next = top.next.next;
        return value;
    }

    @Override
    public void show() {
    
    
        if(isEmpty()) {
    
    
            System.out.println("栈空");
            return;
        }
        System.out.println("当前栈为");
        StackNode temp = top.next;
        while (temp != null) {
    
    
            System.out.println(temp.value);
            temp = temp.next;
        }
    }

    //栈空
    @Override
    public boolean isEmpty() {
    
    
        return top.next == null;
    }

    //这里不设置栈大小,假设栈始终不满
    @Override
    public boolean isFull() {
    
    
        return false;
    }
}

class StackNode {
    
    
    int value; //值
    StackNode next; //指向下一个节点
    StackNode(int value) {
    
    
        this.value = value;
        this.next = null;
    }
}

猜你喜欢

转载自blog.csdn.net/hejnhong/article/details/125525467