❤️《数据结构与算法》系列(二)❤️栈的讲解

目录

💢栈

1.栈的介绍

栈实现

2. 栈的应用场景

3. 栈的快速入门

习题1:使用数组来模拟栈的使用

习题2:回文数

4. 栈实现计算器

 Array S tack

 main

最后


💢


1.栈的介绍

栈是限制插入和删除只能在一个位置上进行的线性表。其中,允许插入和删除的一端位于表的末端,叫做栈顶(top),不允许插入和删除的另一端叫做栈底(bottom)。对栈的基本操作有 PUSH(压栈) 和 POP (出栈) ,前者相当于表的插入操作(向栈顶插入一个元素),后者则是删除操作(删除一个栈顶元素)。栈是一种后进先出(LIFO) 的数据结构,最先被删除的是最近压栈的元素。

image.png

压栈:

image.png

弹栈:

image.png

栈实现

由于栈是一个表,因此任何实现表的方法都可以用来实现栈。主要有两种方式,链表实现和数组实现。

  • 链表实现栈

可以使用单链表来实现栈。通过在表顶端插入一个元素来实现 PUSH,通过删除表顶端元素来实现 POP。使用链表方式实现的栈又叫动态栈。动态栈有链表的部分特性,即元素与元素之间在物理存储上可以不连续,但是功能有些受限制,动态栈只能在栈顶处进行插入和删除操作,不能在栈尾或栈中间进行插入和删除操作

  • 数组实现栈

栈也可以用数组来实现。使用数组方式实现的栈叫静态栈

2. 栈的应用场景

image.png

3. 栈的快速入门

习题1:使用数组来模拟栈的使用

image.png

/**

 * author:韩国庆

 * date:2021/1/18 14:16

 * version:1.0

 */

public class ArrayStack {

    /**

        栈的大小

     */

    private int maxStack;

 

    /**

        数组用来模拟栈

     */

    private int[] stack;

 

    /**

     * 表示栈顶,默认值为-1

     */

private int top = -1;

 

    /**

     *

     * @param maxStack 初始化栈的大小

     */

    public ArrayStack(int maxStack){

        this.maxStack = maxStack;

        this.stack = new int[this.maxStack];

    }

 

    /**

     *  判断是否已经栈满

     * @return

     */

    public boolean isFull(){

        return this.top==maxStack-1;

    }

 

    /**

     * 是否空栈

     */

    public boolean isEmpty(){

        return this.top==-1;

    }

 

    /**

     * 入栈

     */

    public void push(int value){
    if (isFull()){

            throw new RuntimeException("栈已满...");

        }

 

        top++;

        stack[top] = value;

    }

 

    /**

     *出栈

     */

    public int pop(){

        if (isEmpty()){

            throw new RuntimeException("空栈,没有数据");

        }

        int value = stack[top];

        top--;

        return value;

    }

 

    /**

     * 查看栈中数据

     */

    public void list(){

        if (isEmpty()){

            throw new RuntimeException("空栈,没有数据");

        }

        for (int i=0;i<stack.length;i++){

            System.out.printf("stack[%d]=%d\n",i,stack[i]);

        }
        }

 

 

}

习题2:回文数

回文: 一个单词、短语或数字,从前往后写和从后往前写都是一样的。比如,单词“dad”、“racecar”就是回文;如果忽略空格和标点符号,下面这个句子也是回文,“A man, a plan, a canal: Panama”, 数字1001 也是回文。

思路:使用栈,可以轻松判断一个字符串是否是回文。我们将拿到的字符串的每个字符按从左至右的顺序压入栈。当字符串中的字符都入栈后,栈内就保存了一个反转后的字符串,最后的字符在栈顶,第一个字符在栈底


        ArrayStack arrayStack = new ArrayStack(10);

        int length = words.length();

        for (int i=0;i<length;i++){

            arrayStack.push(words.charAt(i));

        }

        String newValue = "";

        for (int i=0;i<arrayStack.length();i++){

            if (!arrayStack.isEmpty()){

                Object value = arrayStack.pop();

                newValue = newValue+value;

            }

        }

        if (words.equals(newValue)){

            return true;

        }

        return false;

    }

4. 栈实现计算器

思维分析结果图:

image.png

 Array S tack


    /**

        栈的大小

     */

    private int maxStack;

 

    /**

        数组用来模拟栈

     */

    private int[] stack;

 

    /**

     * 表示栈顶,默认值为-1
     */

    private int top = -1;

 

    /**

     *

     * @param maxStack 初始化栈的大小

     */

    public ArrayStack(int maxStack){

        this.maxStack = maxStack;

        this.stack = new int[this.maxStack];

    }

 

    /**

     *  判断是否已经栈满

     * @return

     */

    public boolean isFull(){

        return this.top==maxStack-1;

    }

 

    /**

     * 是否空栈

     */

    public boolean isEmpty(){

        return this.top==-1;

    }

 

    /**

     * 入栈

     */
     public void push(int value){

        if (isFull()){

            throw new RuntimeException("栈已满...");

        }

 

        top++;

        stack[top] = value;

    }

 

    /**

     *出栈

     */

    public int pop(){

        if (isEmpty()){

            throw new RuntimeException("空栈,没有数据");

        }

        int value = stack[top];

        top--;

        return value;

    }

 

    /**

     * 查看栈中数据

     */

    public void list(){

        if (isEmpty()){

            throw new RuntimeException("空栈,没有数据");

        }

        for (int i=0;i<stack.length;i++){

            System.out.printf("stack[%d]=%d\n",i,stack[i]);
            }

    }

 

    /**

     * 查看栈大小

     * @return

     */

    public int length(){

        return stack.length;

    }

 

    /**

     * 查看栈顶

     * @return

     */

    public int peek(){

        return stack[top];

    }

 

    /**

     * 运算符优先级

     * 数字越大优先级越高

     */

    public int priority(int oper){

        if (oper=='*' || oper=='/'){

            return 1;

        }else if (oper=='+' || oper=='-'){

            return 0;

        }else {

            return -1;
            }

 

    }

    /**

     * 判断是否是一个运算符

     */

    public boolean isOper(char v){

        return v=='+' || v=='-'||v=='*'||v=='/';

    }

 

    /**

     * 计算

     */

    public int calculate(int num1,int num2,int oper){

        int res = 0;

        switch (oper){

            case '+':

                res=num1+num2;

                break;

            case '-':

                res=num2-num1;

                break;

            case '*':

                res=num1*num2;

                break;

            case '/':

                res=num2/num1;

                break;

 

                default:
                break;

 

        }

        return res;

    }

 main


 

 

        String str = "3+2*3-1-1";

 

        ArrayStack numStack = new ArrayStack(10);

        ArrayStack symbolStack = new ArrayStack(10);

        int length = str.length();

        int temp1 = 0;

        int temp2 = 0;

        int symbolChar = 0;

        int result = 0;

        String values = "";

        for (int i=0;i<length;i++) {

            //获取每一个字符

            char c = str.charAt(i);

            //判断是否是一个字符

            if (symbolStack.isOper(c)){

                //如果字符栈中不是空栈

                if (!symbolStack.isEmpty()){

                    //如果当前字符优先级小于等于字符栈中存在的

                    if
                    (symbolStack.priority(c)<=symbolStack.priority(symbolStack.peek())){

                        /**

                         * 即从数字栈中pop出来两个数字,再从符号栈中pop出来一个符号进行计算,然后把结果

                         * 然后把结果再次存入栈中

                         */

                        temp1 = numStack.pop();

                        temp2 = numStack.pop();

                        symbolChar = symbolStack.pop();

                        result = numStack.calculate(temp1,temp2,symbolChar);

                        //把计算结果再次放入栈中

                        numStack.push(result);

                        //把当前符号放入栈中

                        symbolStack.push(c);

                    }else {

                        //如果当前符号优先级大于符号栈中的符号,直接放入符号栈中

                        symbolStack.push(c);

                    }

                }else {

                    //如果符号栈中是空,则也直接如符号栈

                    symbolStack.push(c);

                }

            }else {

                //如果扫描的是数字。数字很能存在多位,比如33,22,100,如何能保证这多位数字

                //判断当前字符后一位是否是一个字符,如果是字符表示当前数字结束直接存入数字栈,如果不是字符,表示

                //这是一个多位数字
                values+=c;

                if (i==length-1){//表示是最后一个数字,可以直接存放在数字栈中

                    numStack.push(Integer.parseInt(values));

                }else {

                    char data = str.substring(i+1, i + 2).charAt(0);

                    if (symbolStack.isOper(data)){//如果是符号,则把数字存入数字栈中,并清空values。

                        numStack.push(Integer.parseInt(values));

                        values="";

                    }

                }

 

            }

        }

 

        while (true){

            if (symbolStack.isEmpty()){

                break;

            }

            temp1 = numStack.pop();

            temp2 = numStack.pop();

            symbolChar = symbolStack.pop();

            result = numStack.calculate(temp1,temp2,symbolChar);

            numStack.push(result);

        }

        int res = numStack.pop();

        System.out.println("结果是:"+res);
        }

最后

目前市面上更多的是C语言,C++版的数据结构和算法,极少有关于Java数据结构和算法的课程,所以Java程序员往往需要跨语言学习,难度和效率大大折扣!

今天,也分享给大家一套Java的数据结构和算法教程,一套属于咱Java程序员的数据结构和算法课程,帮助广大Java程序员,系统化深度学习数据结构和算法,掌握其中要领实现华丽转身,进大厂,升职加薪指日可待!

https://www.bilibili.com/video/BV1HQ4y1d7th

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

牛仔码农@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值