算法通关村——如何基于数组和链表实现栈

一、什么是栈

       栈的特性:后进先出、先进后出

       栈的基本操作:

  • push(E):增加一个元素E
  • pop0:弹出元素E
  • peek0:显示栈顶元素,但是不出栈
  • empty0:判断栈是否为空   

二、基于数组实现栈

将栈的出入当作数组元素添加和删除,还需要考虑到数组是有长度限制的,所以我们要在入栈前判断是否需要扩容。

import java.util.Arrays;

public class MyStack<T> {
    //实现栈的数组
    private Object[] stack;
    //指向栈顶的上面一个位置 也表示栈的数量
    private int top;

    //初始化栈,初始容量是10
    public MyStack(){
        stack = new Object[10];
    }

    //入栈
    public void push(T t) {
        expandCapacity(top + 1);
        stack[top] = t;
        top++;
    }

    //显示栈顶元素
    public T peek() {
        T t = null;
        if (top > 0) {
            t = (T) stack[top - 1];
        }
        return t;
    }

    //出栈
    public T pop() {
        T t = peek();
        if (top > 0) {
            top--;
            stack[top] = null;
        }
        return t;
    }

    //判空
    public boolean isEmpty() {
        return top == 0;
    }

    //扩大容量
    private void expandCapacity(int size) {
        int len = stack.length;
        if (size > len) {
            size = size * 3 / 2 + 1;  //扩容1.5倍
            Arrays.copyOf(stack, size);
        }
    }
}

三、基于链表实现栈

基于链表实现栈就是将新元素添加在表头,那么在出栈的的时候就会将后放入的节点取出来。

实现:维护一个虚礼表头,使入栈的元素添加到虚礼表头的next,出栈时取出虚礼表头的next并删除。

public class ListStack<T> {

    class Node{
        T t;
        Node next;
        public Node(T t) {
            this.t = t;
        }
    }

    //虚礼头节点
    private Node dummyNode;
    public ListStack() {
        this.dummyNode = new Node(null);
    }

    //入栈
    public void push(T t){
        Node node = new Node(t);
        node.next = dummyNode.next;
        dummyNode.next = node;
    }

    //显示栈顶元素
    public T peek(){
        T t = null;
        if (!isEmpty()){
            t = dummyNode.next.t;
        }
        return t;
    }

    //出栈
    public T pop(){
        T t = peek();
        if (!isEmpty()){
            dummyNode.next = dummyNode.next.next;
        }
        return t;
    }

    //判空
    public boolean isEmpty(){
        return dummyNode.next == null;
    }
}

四、使用双向链表实现栈

以LinkedList作为底层数据结构实现栈时,我们利用其特性:可以从链表的头部(或尾部)高效地插入和删除元素。维护一个LinkedList对象来存储栈中的元素。

import java.util.LinkedList;

public class LinkedListStack<T> {

    private LinkedList<T> linkedList;

    public LinkedListStack() {
        linkedList = new LinkedList<>();
    }

    //入栈
    public void push(T t){
        linkedList.addFirst(t);
    }

    //显示栈顶元素
    public T peek(){
        return linkedList.peekFirst();
    }

    //出栈
    public T pop(){
        return linkedList.removeFirst();
    }

    //判空
    public boolean isEmpty(){
        return linkedList.isEmpty();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值