算法通关村—如何基于数组(或者链表)实现栈

栈和队列是比较特殊的线性表,又称之为访问受限的线性表。钱是很多表达式、符号等运算的基础,也是
递归的底层实现。理论上递归能做的题目栈都可以,只是有些问题用栈会非常复杂。

栈底层实现仍然是链表或者顺序表,栈与线性表的最大区别是数据的存取的操作被限制了,其插入和删除
操作只允许在线性表的一端进行。

「栈 Stack」是一种遵循先入后出(First In, Last Out)原则的线性数据结构。

图片来源:https://www.hello-algo.com/chapter_stack_and_queue/stack/

栈的操作

  • push (E) 增加一个元素 E
  • pop()弹出一个元素
  • peek()显示栈顶元素,但是不会弹出
  • empty()判断栈是否为空

手动实现

再看具体内容之前,先补充一点,top 有的地方指向栈顶元素,有的地方指向栈顶再往上的一个空单位,这
个根据题目要求设计就好,如果是面试的时候就直接问面试官,top 指向到哪里,本文采用指向栈顶空位 置

数组

在这里插入图片描述
只要注意一点就可以, top-- 和 top - 1 有根本的不同 ! top-- 相当于 top = top - 1

注意 top-- 和 --top 也有区别 !

  1. top-- 是先使用top的值,然后再将 top 减 1
  2. --top 则是先将 top 减 1,然后再使用减 1 后的值
int top = 5;
int result1 = top--; // result1 = 5, top = 4
int result2 = --top; // result2 = 3, top = 3

实现代码

import java.util.Arrays;

/**
 * @author leikooo
 */
class Mystack<T> {
   /**
    * 实现栈的数组
    */
    private Object[] stack;
   /**
    * 栈顶元素
    */
    private int top;

    Mystack() {
        //初始容量为10
        stack = new Object[10];
    }

    /**
     * 判断是否为 null
     *
     * @return
     */
    public boolean isEmpty() {
        return top == 0;
    }

    /**
     * 返回栈顶元素
     *
     * @return
     */
    public T peek() {
        T t = null;
        if (top > 0) {
            t = (T) stack[--top];
        }
        return t;
    }

    /**
     * 取出元素
     *
     * @return
     */
    public T pop() {
        T t = peek();
        if (top > 0) {
            stack[top] = null;
        }
        return t;
    }

    /**
     * 增加元素
     *
     * @param t
     */
    public void push(T t) {
        expandCapacity(stack.length);
        stack[top] = t;
        top++;
    }

    /**
     * 扩大容量
     *
     * @param size
     */
    public void expandCapacity(int size) {
        int len = stack.length;
        if (size > len) {
        	// 每次扩大50%
            size = size * 3 / 2 + 1;
            stack = Arrays.copyOf(stack, size);
        }
    }
	
    public static void main(String[] args) {
        Mystack<String> stack = new Mystack<>();
        System.out.println(stack.peek());
        System.out.println(stack.isEmpty());
        stack.push("java");
        stack.push("is");
        stack.push("beautiful");
        stack.push("language");
        // 正在学习日语😎
        stack.push("りゆ");
        System.out.println(stack.pop());
        System.out.println(stack.isEmpty());
        System.out.println(stack.peek());
    }
}

链表

链表也可以实现栈,插入和删除都在头结点进行就可以了

在这里插入图片描述

/**
 * @author leikooo
 */
class ListStack<T> {
    //定义链表
    class Node<T> {
        public T t;
        public Node next;
    }

    public Node<T> head;

    //构造函数初始化头指针
    ListStack() {
        head = null;
    }

    /**
     * 是否为 null
     *
     * @return
     */
    public boolean isEmpty() {
        return head == null;
    }

    /**
     * 取出头节点元素
     */
    public T peek() {
        return (T) head.t;
    }

    /**
     * 入栈
     */
    public void push(T t) {
        // 初始化需要插入的 节点
        Node<T> tNode = new Node<T>();
        tNode.t = t;
        // 直接替换头节点
        tNode.next = head;
        head = tNode;
    }

    /**
     * 出栈
     * @return
     */
    public T pop () {
        T peek = peek();
        if (head.next == null) {
            head = null;
        }
        head = head.next;
        return peek;
    }

    public static void main(String[] args) {
        ListStack stack = new ListStack();
        System.out.println(stack.isEmpty());
        stack.push("Java");
        stack.push("is");
        stack.push("beautiful");
        System.out.println(stack.peek());
        System.out.println(stack.pop());
        System.out.println(stack.isEmpty());
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值