Java中栈(Stack)

目录

何为栈:

Java 标准库中的栈 Stack

模拟实现栈

基于数组:

 基于顺序表:

 基于链表:

 栈的练习


何为栈:

栈:棚也,字典对其释译之一是储存货物或供旅客住宿的房屋,在计算机中栈可以看作是数据歇脚的地方,对数据进行暂时存储,数据入栈相当于办理入住向JVM申请空间,当程序运行结束时,相关数据就会从栈中弹出释放空间,就像数据退房离开了一样。

概念:一个只允许在固定一端进行插入和删除元素操作的特殊线性表(一个前驱一个后继)。遵循后进先出(LIFO)原则

          前驱:栈中位于其下方的元素。

          后继:栈中位于其上方的元素。

Java 标准库中的栈 Stack

继承自 Vector 类

from Java Documentation 

 1. empty()   判断栈是否为空
 2. peek()     查看栈顶元素
 3. pop()       出栈(从栈顶开始)并将其从栈中删除
 4. push()     入栈
 5. clear()     清空栈中所有元素
 6. search()  从栈顶开始搜索指定元素在栈中的位置,找到则返回其距离栈顶的位置(栈顶为1),如果未找到则返回-1。

 7. size()      获取栈中有效元素

//import java.util.Stack; 
//public class Test {
    //public static void main(String[] args) {
    // 使用标准库的栈
    //Stack<String> stack = new Stack<>();

    //入栈
    //stack.push("aa");
    //stack.push("bb");
    //stack.push("cc");

    //此时栈中
    //cc
    //bb
    //aa

    //取栈顶元素
    //String top = stack.peek();
    //System.out.println(top);

    //出栈
    //String s = stack.pop();
    //System.out.println(s);
    //s = stack.pop();
    //System.out.println(s);
    //s = stack.pop();
    //System.out.println(s);
    //}
//}

         // 运行结果

         cc    // 栈顶元素
         cc    
         bb
         aa

模拟实现栈

基于数组:

讲数组的尾部看作栈顶,从这里压入新元素,同样从这里出,实现后进先出的效果

// 基于数组
public class MyStack {
    private String[] arr;
    private int size;

    public MyStack(){
        arr = new String[1000];
        size = 0;
    }

    public MyStack(int capacity) {
        arr = new String[capacity];
        size = 0;
    }

    public void resize(){
        // 创建一个更长的数组
        String[] newArr = new String[arr.length * 2];
        // 复制原数组
        for(int i = 0; i < arr.length; i++){
            newArr[i] = arr[i];
        }
        // 用新数组替换旧数组
        arr = newArr;
    }
    // 入栈
    // elem element 元素
    public void push(String elem){
        if(size == arr.length){
            // 扩容
            resize();
        }
        // 实现一个尾插
        arr[size] = elem;
        size++;
    }

    // 出栈
    public String pop(){
        if(size == 0){
            throw new RuntimeException("Stack is empty");
        }
        // 取出栈顶元素
        String elem = arr[size - 1];
        size--;
        return elem;
    }

    // 获取栈顶元素
    public String peek(){
        if(size == 0){
            throw new RuntimeException("Stack is empty");
        }
        String elem = arr[size - 1];
        return elem;
    }

    public static void main(String[] args) {
        // 测试
        MyStack stack = new MyStack();
        stack.push("aaa");
        stack.push("bbb");
        stack.push("ccc");
        System.out.println(stack.peek());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());

        System.out.println(stack.peek());
    }
}

 基于顺序表:

借助 ArrayList 类的方法来实现栈的入栈、出栈、查看栈顶元素等基本操作。ArrayList 是动态数组,可自动扩容,所以无需像基于数组实现栈那样手动处理扩容问题。
 

import java.util.ArrayList;
import java.util.Scanner;
// 基于ArrayList
public class MyStack2 {
    private ArrayList<String> stack;

    public MyStack2(){
        stack = new ArrayList<>();
    }

    // size
    public int size(){
        return stack.size();
    }

    // 判断是否为空
    public boolean isEmpty(){
        return stack.isEmpty();
    }

    // 入栈
    public void push(String elem){
        // 尾插
        stack.add(elem);
    }

    // 出栈
    public String pop(){
        // 判断是否为空
        if(!isEmpty()){
            throw new RuntimeException("Stack is empty");
        }
        // 尾删
        return stack.remove(stack.size() - 1);
    }

    // 查看栈顶元素
    public String peek(){
        // 判断是否为空
        if(!isEmpty()){
            throw new RuntimeException("Stack is empty");
        }
        // 获取最后一个元素
        return stack.get(stack.size() - 1);
    }
    public static void main(String[] args) {
        MyStack2 stack = new MyStack2();
        stack.push("a");
        stack.push("b");
        stack.push("c");
        System.out.println("Top element: " + stack.peek());
        System.out.println("Popped element: " + stack.pop());
        System.out.println("Stack size: " + stack.size());
    }
}

 基于链表:

 链表知道头节点便可得到整个链表,可以直接 将头节点作为栈顶

package stack;

import java.util.Scanner;


    // 定义链表节点类
    class Node {
        String elem;
        Node next;

        public Node(String elem) {
            this.elem = elem;
            this.next = null;
        }
    }

    // 基于链表实现的栈类
    public class MyStack3 {
        private Node head;
        private int size;

        // 构造函数,初始化栈
        public MyStack3() {
            head = null;
            size = 0;
        }

        // 判断栈是否为空
        public boolean isEmpty() {
            return head == null;
        }

        // 获取栈的大小
        public int size() {
            return size;
        }

        // 入栈操作
        public void push(String elem) {
            Node newNode = new Node(elem);
            newNode.next = head;
            head = newNode;
            size++;
        }

        // 出栈操作
        public String pop() {
            if (isEmpty()) {
                throw new RuntimeException("Stack is empty, cannot pop.");
            }
            String elem = head.elem;
            head = head.next;
            size--;
            return elem;
        }

        // 查看栈顶元素
        public String peek() {
            if (isEmpty()) {
                throw new RuntimeException("Stack is empty, cannot peek.");
            }
            return head.elem;
        }

        public static void main(String[] args) {
            MyStack3 stack = new MyStack3();
            stack.push("a");
            stack.push("b");
            stack.push("c");
            System.out.println("Top element: " + stack.peek());
            System.out.println("Popped element: " + stack.pop());
            System.out.println("Stack size after pop: " + stack.size());
        }
    }

     此处栈本质上就是一个顺序表 / 链表,但是在其基础上做出了限制,禁止了顺序表 / 链表的各种增删改查操作,只支持三个操作,入栈、出栈、取栈顶元素。可以认为其就是只支持尾插、尾删、获取尾部元素的顺序表或者链表 

 栈的练习

leetCode 有效的括号

逆波兰表达式       逆波兰表达式答案

最小栈

答案正在骑码来的路上 ......

                                                                                                                              To be continued 
                                                                                                                               欢迎评论✨

或许你会有一天怀念,可是我已不再—    小镇姑娘 DT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值