数据结构之栈的讲解

 

 💕"

春宵一刻值千金,花有清香月有阴。

"💕

作者:Mylvzi 

 文章主要内容:leetcode刷题之哈希表的应用(1) 

1.栈的概念

  栈是一种只允许在一端(栈顶)进行数据操作的数据结构,具有“后进先出”的特性,也叫做Last in First Out

最常见的现实生活中的例子就是压子弹  只能一端压子弹

2.栈的模拟实现

  我们想想什么可以实现栈的操作呢?我们知道,栈最大的特性就行只能在一端进行数据操作,使用数组可以更好的模拟栈

  数组的末尾就是我的栈顶,操作栈顶就是操作数组的最后一个元素,而数组最后一个元素的添加,删除都很方便!!!

 1.使用数组模拟

public class MyStack {
    /**
     * 栈的实现一:用数组实现栈
     */
    private int[] elem;
    private int usedSize;

    private static final int DEFAULTCAPACITY = 10;

    public MyStack() {
        this.elem = new int[DEFAULTCAPACITY];
    }

    public MyStack(int size) {
        this.elem = new int[size];
    }

    public void push(int val) {
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }

        this.elem[usedSize] = val;
        this.usedSize++;
    }

    private boolean isFull() {
        return this.usedSize == this.elem.length;
/*        if (this.elem.length == this.usedSize) {
            return true;
        }

        return false;*/
    }

    public int pop() {
        if (isEmpty()) {
            throw new StackEmptyException("栈区之内不含有数据,无法删除");
        }

//        this.usedSize--;
//        return this.elem[usedSize];

        int oldVal = this.elem[usedSize-1];
        this.usedSize--;
        return oldVal;
    }

    public int peek() {
        if (isEmpty()) {
            throw new StackEmptyException("栈区之内不含有数据,无法删除");
        }

        return this.elem[usedSize-1];
    }

    public boolean isEmpty() {

        return this.usedSize == 0;
/*        if (this.usedSize == 0) {
            return true;
        }

        return false;*/
    }

}

2.使用链表模拟

当然除了使用数组模拟栈,使用链表也可以实现栈的功能(Java中的LinkedList本质上是一个无头双向非循环链表)

class Mystack3 {
    // 使用链表模拟栈
    /**
     * 栈只能在一端进行数据的操作
     * 在这里我们只在链表的last进行数据的操作
     */
    LinkedList<Integer> mystack = new LinkedList<>();

    // push
    public void push(int data) {
        mystack.addLast(data);
    }

    // pop
    public int pop() {
        if(mystack.isEmpty()) {
            return -1;// 抛异常也可以
        }
        return mystack.pollLast();
    }

    public int peek() {
        return mystack.peekLast();
    }

    public static void main(String[] args) {
        Mystack3 mystack3 = new Mystack3();
        mystack3.push(1);
        mystack3.push(2);
        mystack3.push(3);

        System.out.println(mystack3.pop());// 3
        System.out.println(mystack3.peek());// 2
    }
}

3.Java中的栈Stack

  Java中提供了现成的栈供我们使用

代码演示 

// 栈的创建  栈在Java中就是一个类!!!
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);

        // 使用构造器
        Iterator<Integer> it= stack.iterator();
        while (it.hasNext()) {
            System.out.print(it.next()+" ");// 1 2 3 4
        }
        System.out.println();
        System.out.println("============================");
        // 重写了toString方法  直接传对象 即可打印内容
        System.out.println(stack);// 1 2 3 4

        // pop会删除栈顶元素
        stack.pop();
        System.out.println(stack);// 1 2 3

        // peek  瞄一眼  不会把top删除
        int x = stack.peek();
        System.out.println(x);// 3
    }

 4.栈的应用场景

1.括号匹配问题

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/

分析:

代码实现:

class Solution {
    public static boolean isValid(String s) {
        if(s.length() % 2 != 0) return false;
        Stack<Character> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            // 获取当前字符
            char ch = s.charAt(i);
            // 左括号
            if(ch == '(' || ch == '{' || ch == '[') {
                stack.push(ch);
            }else {// 右括号
                if(stack.isEmpty()) {
                   return false;
                }else {
                    // 要进行括号匹配
                    char top = stack.peek();

                    if(ch == '}' && top == '{' || ch == ')' && top == '(' ||ch == ']' && top == '[') {
                        stack.pop();
                    }else {
                        return false;
                    }
                }
            }
        }

        return stack.isEmpty();

    }
}

也可以使用顺序表实现

class Solution {
    public static boolean isValid(String s) {
        if(s.length() % 2 != 0) return false;
        List<Character> list = new ArrayList<>();

        for (int i = 0; i < s.length(); i++) {
            // 获取当前字符
            char ch = s.charAt(i);
            // 左括号
            if(ch == '(' || ch == '{' || ch == '[') {
                list.add(ch);
            }else {// 右括号
                if(list.isEmpty()) {
                   return false;
                }else {
                    // 要进行括号匹配
                    char top = list.get(list.size()-1);

                    if(ch == '}' && top == '{' || ch == ')' && top == '(' ||ch == ']' && top == '[') {
                        list.remove(list.size()-1);
                    }else {
                        return false;
                    }
                }
            }
        }

        return list.isEmpty();

    }

}

2.后缀表达式

 代码实现:

class Solution {
    public int evalRPN(String[] tokens) {
        // 遇到数字存放到栈中
        Stack<Integer> stack = new Stack<>();

        // 循环遍历所给字符串
        for(String s : tokens) {
            // 数字
            if(!isOperation(s)) {
                // 是数字就push
                stack.push(Integer.parseInt(s));
            }else {// 运算符
            // 先弹出的作右运算符  后弹出的是左运算符
                int num2 = stack.pop();
                int num1 = stack.pop();

                switch(s) {
                    case "+":
                        stack.push(num1+num2);
                        break;
                    case "-":
                        stack.push(num1-num2);
                        break;
                    case "*":
                        stack.push(num1*num2);
                        break;
                    case "/":
                        stack.push(num1/num2);
                        break;    
                }

            }
        }

        // 遍历完  返回栈的最后一个(唯一一个)元素
        return stack.pop();

    }

    // 判断是否是运算符
    private boolean isOperation(String s) {
        if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
            return true;
        }

        return false;
    }
}

 3.最小栈

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台icon-default.png?t=N7T8https://leetcode.cn/problems/min-stack/submissions/分析思路:

代码实现:使用两个栈

    class MinStack {
        //思路1 使用两个栈
        private Stack<Integer> stack;
        private Stack<Integer> minstack;// 存放过程中的最小值


        public MinStack() {
            this.stack = new Stack<>();
            this.minstack = new Stack<>();
        }
        

        public void push(int val) {
            if(minstack.isEmpty()) {
                minstack.push(val);
            }else {
                if (val <= minstack.peek()) {
                    minstack.push(val);
            }
            }

            stack.push(val);

        }

        public void pop() {
            if(!stack.isEmpty()) {
                int top = stack.pop();
                if (top == minstack.peek()) {
                    minstack.pop();
            }
            
            }
            
        }

        public int top() {
            if(stack.empty()) {
            return -1;
        }
            return stack.peek();
        }

        public int getMin() {
            if (minstack.isEmpty()) {
                return -1;
            }
            return minstack.peek();
        }
    }

 思路2:使用链表实现

画图分析

代码实现

 class MinStack {
        // 使用链表实现
        private class Node{
            int val;
            int min;
            Node next = null;

            public Node(int val, int min) {
                this.val = val;
                this.min = min;
            }
        }
        
        private Node head;

        public void push(int x) {
            if(head == null) {
                head = new Node(x,x);
            }else {
                Node newNode = new Node(x,Math.min(x,head.min));
                newNode.next = head;
                head = newNode;
            }

        }

        public void pop() {
            head = head.next;
        }

        public int top() {
            return head.val;
        }

        public int getMin() {
            return head.min;
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/171284.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工作记录---淘宝双11,亿级流量高并发是怎么抗住?(站在巨人的肩膀上学习,超开心~)--------脚踏实地,持续学习(看完这一篇获益匪浅)

什么是分布式&#xff1f; 系统中的多个模块在不同服务器上部署&#xff0c;即可称为分布式系统。 如Tomcat和数据库分别部署在不同的服务器上&#xff0c;或两个相同功能的Tomcat分别部署在不同服务器上。 什么是高可用&#xff1f; 系统中部分节点失效时&#xff0c;其他节…

大数据基础设施搭建 - Kafka(with ZooKeeper)

文章目录 一、简介二、单机部署2.1 上传压缩包2.2 解压压缩包2.3 修改配置文件&#xff08;1&#xff09;配置zookeeper地址&#xff08;2&#xff09;修改kafka运行日志(数据)存储路径 2.4 配置环境变量2.5 启动/关闭2.6 测试&#xff08;1&#xff09;查看当前服务器中的所有…

米诺地尔行业分析:预计2029年将达到14亿美元

米诺地尔市场规模庞大&#xff0c;不仅包括消费品市场和服务行业&#xff0c;还涵盖了创新科技领域。随着经济的发展和市场需求的不断增长&#xff0c;米诺地尔市场的规模将继续扩大&#xff0c;各行各业都将面临更多机遇和挑战。 随着社会经济发展和城市化进程的推进&#xff…

怎么实现在微信公众号秒杀商品的功能呢

实现微信公众号秒杀商品的功能&#xff0c;需要结合微信公众平台和后端开发技术。下面将介绍整个实现过程&#xff0c;包括前期准备、开发流程和后期运营等方面。 一、前期准备 确定秒杀商品&#xff1a;选择适合秒杀的商品&#xff0c;要求数量充足、质量良好&#xff0c;同时…

NOSQL----redis的安装和基础命令

redis是什么 1.redis-------非关系型数据库 redis是非关系数据库的一种&#xff0c;也称为缓存型数据库。 非关系型数据库和关系型数据库 1.关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;记录方式是行和列&#xff08;列&#xff1a;声明对象&#xff0c;行&am…

Python二级 每周练习题27

如果你感觉有收获&#xff0c;欢迎给我打赏 ———— 以激励我输出更多优质内容 练习一: 用户输入一个半径r&#xff0c;求该半径下的圆的面积s与周长c。要求如下&#xff1a; &#xff08;1&#xff09;输出的面积与周长都保留俩位小数&#xff1b; &#xff08;2&#xff0…

王先生丢手机上热搜!VERTU放大招:推出真人找手机服务

日前&#xff0c;一则关于民警三小时帮助失主寻回三十万天价手机的新闻登上热搜&#xff0c;引发网友对这部三十万手机的好奇与猜测。据了解&#xff0c;该男子丢失的手机疑似为一款名叫VERTU Signature 的奢侈品定制手机&#xff0c;而根据其官网显示&#xff0c;“唐卡定制”…

家庭教育专家:如何创建家庭自主学习环境?

经常听到一些父母这样抱怨&#xff1a;“明明和孩子说好就看20分钟电视&#xff0c;结果到了时间&#xff0c;他死活都不肯关。”“作业还没完成的情况下&#xff0c;孩子还一直抱着手机或者电子产品玩游戏。到了约定时间也不撒手&#xff0c;一直跟你讨价还价。” 其实&#…

图像处理02 matlab中NSCT的使用

06 matlab中NSCT的使用 最近在学习NSCT相关内容&#xff0c;奈何网上资源太少&#xff0c;简单看了些论文找了一些帖子才懂了一点点&#xff0c;在此分享给大家&#xff0c;希望有所帮助。 一.NSCT流程 首先我们先梳理一下NSCT变换的流程&#xff0c;只有清楚流程才更好的理清…

Redis(位图Bitmap和位域Bitfield)

位图&#xff1a; 位图是字符串类型的扩展。 Redis中的位图是一种特殊的数据结构&#xff0c;用于表示一系列位的集合。它可以存储大量的布尔值数据&#xff0c;每个位代表一个布尔值&#xff08;0或1&#xff09;&#xff0c;并且可以对这些位进行各种位运算操作。位图通常用…

【ARM Trace32(劳特巴赫) 使用介绍 2.3 -- TRACE32 进阶命令之 参数传递介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 参数传递命令 ENTRY 参数传递命令 ENTRY ENTRY <parlist>The ENTRY command can be used to Pass parameters to a PRACTICE script or to a subroutineTo return a value from a subroutine 使用示例&am…

C++入门第八篇---STL模板---list的模拟实现

前言&#xff1a; 有了前面的string和vector两个模板的基础&#xff0c;我们接下来就来模拟实现一下list链表模板&#xff0c;我还是要强调的一点是&#xff0c;我们模拟实现模板的目的是熟练的去使用以及去学习一些对于我们本身学习C有用的知识和用法&#xff0c;而不是单纯的…

泛型进阶:通配符

基本概念 对泛型不了解的可以看这篇博客&#xff1a;数据结构前瞻-CSDN博客 一般来说&#xff0c;&#xff1f;在泛型里的使用就是通配符 看看下面的代码 class Message<T> {private T message ;public T getMessage() {return message;}public void setMessage(T m…

Qml使用cpp文件的信号槽

文章目录 一、C文件Demo二、使用步骤1. 初始化C文件和QML文件&#xff0c;并建立信号槽2.在qml中调用 一、C文件Demo Q_INVOKABLE是一个Qt元对象系统中的宏&#xff0c;用于将C函数暴露给QML引擎。具体来说&#xff0c;它使得在QML代码中可以直接调用C类中被标记为Q_INVOKABLE的…

【Sql】sql server还原数据库的时候,提示:因为数据库正在使用,所以无法获得对数据库的独占访问权。

【问题描述】 sql server 还数据库的时候&#xff0c;提示失败。 点击左下角进度位置&#xff0c;可以得到详细信息&#xff1a; 因为数据库正在使用&#xff0c;所以无法获得对数据库的独占访问权。 【解决方法】 针对数据库先后执行下述语句&#xff0c;获得独占访问权后&a…

Python 和 Ruby 谁是最好的Web开发语言?

Python 和 Ruby 都是目前用来开发 websites、web-based apps 和 web services 的流行编程语言之一。 【这个时候又人要说PHP是世界上最好的语言了】 我就不说PHP 最好的方法 VS 以人为本的语言 社区: 稳定与创新 尽管特性和编程哲学是选择一个语言的首要驱动因素&#xff0c…

stack和queue简单实现(容器适配器)

容器适配器 stack介绍stack模拟实现queue 介绍queue模拟实现deque stack介绍 stack模拟实现 以前我们实现stack&#xff0c;需要像list,vector一样手动创建成员函数&#xff0c;成员变量。但是stack作为容器适配器&#xff0c;我们有更简单的方法来实现它。 可以利用模板的强大…

C语言生成dll与lib文件

环境要求 新建一个空白项目&#xff0c;可以是exe的&#xff0c;也可以直接是dll的&#xff0c;也可以是啥都没有的空项目&#xff0c;推荐创建空项目&#xff0c;项目创建好以后进行配置&#xff0c;共两步 第一步&#xff0c;打开项目属性 第二步&#xff0c;设置配置类型…

基础课10——自然语言生成

自然语言生成是让计算机自动或半自动地生成自然语言的文本。这个领域涉及到自然语言处理、语言学、计算机科学等多个领域的知识。 1.简介 自然语言生成系统可以分为基于规则的方法和基于统计的方法两大类。基于规则的方法主要依靠专家知识库和语言学规则来生成文本&#xff0…

java中的抽象

1.当一个类中给出的信息不够全面时&#xff0c;&#xff08;比方说有无法确定的行为&#xff09;&#xff0c;它给出的信息不足以描绘出一个具体的对象&#xff0c;这时我们往往不会实例化该类&#xff0c;这种类就是抽象类。 2. 在Java中&#xff0c;我们通过在类前添加关键字…
最新文章