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

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

理解什么是栈

栈和队列是比较特殊的线性表,又称之为访问受限的线性表。栈是很多表达式、符号等运算的基础,也是递归的底层实现。理论上递归能做的题目栈都可以,只是有些问题用栈会非常复杂。 栈底层实现仍然是链表或者顺序表,栈与线性表的最大区别是数据的存取的操作被限制了,其插入和删除操作只允许在线性表的一端进行。一般而言,把允许操作的一端称为栈顶(Top),不可操作的一端称为栈底(Bottom),同时把插入元素的操作称为入栈(Push),删除元素的操作称为出栈(Pop)。若栈中没有任何元素,则称为空栈,栈的结构如下图:

《算法通关村—如何基于数组(或者链表)实现栈》_第1张图片

栈的常用操作

栈的常用操作主要有:

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

我们在设计自己的栈的时候,不管用数组还是链表,都要实现上面几个方法。 如果想测试一下自己对栈是否理解,做一下这道题就够了:

入栈顺序为1234,所有可能的出栈序列是什么? 这个题是什么意思呢?比如说,我先让1和2入栈,然后 2 和1出栈,然后再让3 和4 入栈再依次出栈,这样就得到了序列2143。 4个元素的全排列共有24种,栈要求符合后进先出,按此衡量排除后即得:

1234√ 1243√ 1324√ 1342√ 1423× 1432√ 
2134√ 2143√ 2314√ 2341√ 2413× 2431√ 
3124× 3142× 3214√ 3241√ 3412× 3421√ 
4123× 4132× 4213× 4231× 4312× 4321√ 

14种可能,10种不可能,如上所示。

在Java中数组实现

package AlgorithmForth;

import java.util.Arrays;

/**
 * 利用数组实现栈
 */
public class MyStackByArray<T> {
    // 实现栈的数组
    private Object[] stack;
    // 栈顶元素位置;
    private int top;
    MyStackByArray(){
        // 初始容量为10;
        stack = new Object[10];
    }

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

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

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

    // 出栈
    public T pop(){
        T t =peek();
        if(top > 0){
            stack[top-1] = null;
            top --;
        }
        return t;
    }
    // 扩大容量
    public void expandCapacity(int size){
        int len = stack.length;
        if(size > len) {
            size = size * 3 / 2 + 1;
            stack = Arrays.copyOf(stack,size);
        }
    }

    public static void main(String[] args) {
        MyStackByArray<String> stack = new MyStackByArray<>();
        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());
    }
}

在Java中用链表实现

package AlgorithmForth;

/**
 * 基于链表实现栈
 */
public class MyStackByLinkedList<T> {
    class Node<T> {
        public T t;
        public Node next;
    }
    public Node<T> head;
    MyStackByLinkedList(){
        head = null;
    }

    // 入栈
    public void push(T t){
        if(t == null){
            throw new NullPointerException("参数不能为空");
        }
        if(head == null) {
            head = new Node<T>();
            head.t = t;
            head.next = null;
        } else {
            Node<T> temp = head;
            head = new Node<>();
            head.t = t;
            head.next = temp;
        }
    }

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

    // 取栈顶元素
    public T peek(){
        if(head == null){
            return null;
        }
        return head.t;
    }

    // 栈空
    public boolean isEmpty(){
        return head == null;
    }

    public static void main(String[] args) {
        MyStackByLinkedList<String> stack = new MyStackByLinkedList();
        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());
    }
}

近期在自学 Java 做项目,加入了一个编程学习圈子,里面有编程学习路线和原创的项目教程,感觉非常不错。还可以 1 对 1 和大厂嘉宾交流答疑,也希望能对大家有帮助,扫 ⬇️ 二维码即可加入。

在这里插入图片描述

也可以点击链接:我正在「编程导航」和朋友们讨论有趣的话题,你⼀起来吧?

也可以加我QQ(2837468248)咨询说明来意!

你可能感兴趣的:(算法学习,算法,链表,数据结构)