java数据结构YZP专栏版-----堆栈

主文章(数据结构的索引目录—进不去就说明我还没写完)
https://blog.csdn.net/grd_java/article/details/122377505
模拟数据结构的网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
源码
  1. 码云:https://gitee.com/yin_zhipeng/data_structures_and_algorithms_in_java.git
堆栈

1. 堆栈,先入后出的数据结构。
2. 同一时刻只允许访问一个数据项,也就是最后一个数据

一、堆栈

1. 数组实现(Stack Array Implementation)

动画演示
  1. 入栈
    请添加图片描述
  2. 出栈
    请添加图片描述
实现思路
  1. 定义一个数组表示栈
  2. 定义一个变量top指向可以入栈的位置初始为0(也可以初始-1,指向最后一个数据)
  3. 入栈:以top为下标插入数据,然后top后移
  4. 出栈:以top为下标取出数据,然后top前移
代码:com/yzpnb/data_structures/stack/array_implementation/Stack.java
  1. 运行效果
    在这里插入图片描述
import java.util.Arrays;

public class Stack<E> {
    private int top = 0;//栈顶指针,总是指向最后一个可插入位置,如果等于array.length,表示栈满
    private Object[] array;//用数组实现
    //构建栈
    public Stack(){
        this.array = new Object[10];//默认栈初始大小10
        System.out.println("栈初始成功!!!初始大小10");
    }
    public Stack(int size){
        this.array = new Object[size];//指定栈大小
        System.out.println("栈初始成功!!!初始大小"+size);
    }

    //栈满
    public boolean isFull(){
        return top==array.length;
    }
    //栈空
    public boolean isEmpty(){
        return top == 0;
    }
    //数组扩容
    private void arrayExtend(){
        array = Arrays.copyOf(array, array.length * 2);
    }

    //入栈
    public void push(E o){
        if(isFull()){//栈满扩容
            arrayExtend();
            System.out.println("栈满扩容");
        }
        array[top] = o;
        top++;
        System.out.println((E)o+"入栈成功");
    }
    //返回栈顶数据,不对栈做操作
    public E peek(){
        if(isEmpty()){
            return null;
        }
        return (E)array[top-1];
    }

    //出栈
    public E pop(){
        if(top == 0){
            throw new RuntimeException("栈已空!!!");
        }
        System.out.print("出栈");
        return (E)array[--top];
    }

    //测试程序
    public static void main(String[] args) {
        Stack<Integer> integerStack = new Stack<>(2);
        integerStack.push(1);
        integerStack.push(2);
        integerStack.push(3);
        System.out.println(integerStack.pop());
        System.out.println(integerStack.pop());
        System.out.println(integerStack.pop());
        System.out.println(integerStack.pop());
    }
}

2. 链表实现(Linked List Implementation)

动画演示
  1. 入栈
    请添加图片描述
  2. 出栈
    请添加图片描述
实现思路
  1. 定义一个链表作为栈,链表每个结点拥有一个前驱
  2. 定义一个变量top指向栈尾(链表最后一个结点)
  3. 入栈:链表长度为空,top指向当前插入结点,当前插入结点前驱为null;否则让新插入结点前驱指向当前top指向的结点,然后top指向当前插入结点
  4. 出栈:top当前指向结点返回,top前移
代码:com/yzpnb/data_structures/stack/linked_list_implementation/Stack.java
  1. 运行效果
    在这里插入图片描述
public class Stack<E> {
    /**
     * 链表结点
     */
    private static class Node<E> {
        E item;
        Stack.Node<E> prev;

        Node(Node<E> prev, E element) {
            this.item = element;
            this.prev = prev;
        }
    }

    private Node<E> top = null;//栈顶,初始为空

    private final Integer MAXSIZE = 65536;//栈最大为65536

    private Integer size = 6;//当前栈大小,初始为6

    private Integer length = 0;//当前元素个数

    //构建栈
    public Stack(){
        System.out.println("栈初始成功,当前栈没有元素,大小为6");
    }
    public Stack(int size){
        this.size = size;
        System.out.println("栈初始成功,当前栈没有元素,大小为"+size);
    }
    public Stack(E e){//直接构建头结点
        Node<E> eNode = new Node<>(null, e);
        this.length++;
        this.top = eNode;
        System.out.println("栈初始成功!!!当前栈顶元素为:"+top.item+",栈大小为6");
    }
    public Stack(E e,int size){//直接构建头结点,指定初始大小
        this.size = size;
        Node<E> eNode = new Node<>(null, e);
        this.top = eNode;
        this.length++;
        System.out.println("栈初始成功!!!当前栈顶元素为:"+top.item+",栈大小为"+size);
    }

    //栈满
    public boolean isFull(){
        return length == size;
    }
    //栈空
    public boolean isEmpty(){
        return length == 0;
    }
    //扩容,每次*2
    private void extendStack(){
        if(size == MAXSIZE){
            throw new RuntimeException("栈大小已达上限!!!");
        }
        if(size*2>=MAXSIZE){
            size = MAXSIZE;
        }else if(size*2<MAXSIZE) {
            size *= 2;
        }
    }

    //入栈
    public void push(E e){
        if(isFull()){//栈满扩容
            extendStack();
            System.out.println("栈满扩容");
        }
        if(top == null){
            Node<E> eNode = new Node<>(null, e);
            this.top = eNode;
            this.length++;
        }else{
            Node<E> eNode = new Node<>(top, e);
            this.top = eNode;
            this.length++;
        }
        System.out.println((E)e+"入栈成功");
    }
    //返回栈顶数据,不对栈做操作
    public E peek(){
        if(isEmpty()){
            return null;
        }
        return top.item;
    }

    //出栈
    public E pop(){
        if(isEmpty()){
            throw new RuntimeException("栈已空!!!");
        }
        System.out.print("出栈");
        E item = top.item;
        top = top.prev;
        this.length--;
        return item;
    }

    //测试程序
    public static void main(String[] args) {
        Stack<Integer> integerStack = new Stack<>(2);
        integerStack.push(1);
        integerStack.push(2);
        integerStack.push(3);
        System.out.println(integerStack.pop());
        System.out.println(integerStack.pop());
        System.out.println(integerStack.pop());
        System.out.println(integerStack.pop());
    }
}

二、实战

1. 字符串反转

思路
  1. 利用栈先进后出特性,依次入栈字符串,然后依次出栈,即可完成反转
动画演示
  1. 入栈
    请添加图片描述
  2. 出栈
    请添加图片描述
代码:
  1. 运行效果
    在这里插入图片描述
import com.yzpnb.data_structures.stack.array_implementation.Stack;

public class StringReverse {
    public static void main(String[] args) {
        String str = "apple";
        Stack<Character> characterStack = new Stack<>();
        for (char c : str.toCharArray()) {
            characterStack.push(c);
        }
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0;i<str.length();i++){
            stringBuffer.append(characterStack.pop());
        }
        System.out.println("\n"+str+"---字符串反转后---"+stringBuffer);
    }
}

2. 括号匹配

题目:判断字符串括号是否配对
  1. 判断字符串中的括号是否配对“a{b(]c}d”,比如这个字符串“(”找不到配对,则程序结束返回不匹配
思路
  1. 遇到左括号,就入栈
  2. 遇到右括号,出栈,比较,不配对程序结束
    在这里插入图片描述
代码:com/yzpnb/data_structures/stack/example/bracket_match/BracketMatch.java
  1. 运行效果
    在这里插入图片描述
    在这里插入图片描述
import com.yzpnb.data_structures.stack.linked_list_implementation.Stack;

public class BracketMatch {
    public static void main(String[] args) {
        String str = "a{b(]c}d";//不匹配的
//        String str = "{[()]}";//匹配的
        Stack<Character> stack = new Stack<>();
        System.out.println("开始匹配字符串:"+str+"的括号是否匹配");
        for (Character c:str.toCharArray()) {
            switch (c){
                case '{' :
                case '[' :
                case '(' :{
                    stack.push(c);
                    break;
                }
                case ')':
                case ']':
                case '}':{
                    System.out.println("匹配右括号:"+c);
                    if(stack.isEmpty()){
                        System.out.println("不匹配");
                        return;
                    }
                    Character peek = stack.peek();//就用来输出一下
                    if(!check(c,stack.pop())){
                        System.out.println(peek+"与括号"+c+"不匹配");//输出
                        return;
                    }
                }
            }
        }
        System.out.println("字符串括号完全匹配");
    }
    public static boolean check(char a,char b){
        System.out.println();
        switch (a) {
            case '}':{
                return b=='{';
            }
            case ']':{
                return b=='[';
            }
            case ')':{
                return b=='(';
            }
        }
        return false;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值