栈(Stack)与队列(Queue,Deque)

news2024/9/21 14:25:46

前言:

栈与队列在数据结构中用法都相对比较简单,是数据结构中经常用到的两种。

1.栈(Stack)

(1)特点:

 先入后出,后入先出。栈的底层就是一个数组(java原生库中),通过对数组的操作来实现栈的相关操作。栈也是可以用链表(LinkedList)来实现的,在LinkedList这个类中也有push,pop,peek等方法,足以说明栈可以用LinkedList来实现。栈继承了Vector类(这个类中也有一个判空的方法isEmpty() ),可以使用在这个类中的所有非私用方法。

(2)方法:

这里push,pop,empty时间和空间复杂度都为O(1)。 empty判空是定义了一个变量,用来计数。

(3)OJ题:

1)逆波兰表达式求值:

题析:

题解:

import java.util.Stack;
class Solution {
    public boolean isOperation(String x) {
        if(x.equals("+") | x.equals("-") | x.equals("*") | x.equals("/")) {
            return false;
        }
        return true;
    }
    public int evalRPN(String[] tokens) {
        Stack<String> stack = new Stack<>();
        for(String x : tokens) {
            if(!isOperation(x)) {
                //如果不是数字
                int num1 = Integer.parseInt(stack.pop()); //栈顶元素 => 放在右边
                int num2 = Integer.parseInt(stack.pop()); //栈顶后面一个元素 => 放在左边
                switch(x) {
                    case "+":
                        stack.push(String.valueOf((num2 + num1)));
                        break;
                    case "-":
                        stack.push(String.valueOf((num2 - num1)));
                        break;
                    case "*":
                        stack.push(String.valueOf((num2 * num1)));
                        break;
                    case "/":
                        stack.push(String.valueOf((num2 / num1)));
                        break;
                    default:
                        break;
                }
            }else {
                stack.push(x);
            }
        }
        return Integer.parseInt(stack.peek());
    }
}

2)括号匹配: 

题析:

题解:

import java.util.Stack;
class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        char[] arr = s.toCharArray();
        for(char x : arr) {
            if(stack.empty())
            {
                stack.push(x);
            }else {
                if(stack.peek() == '(' && x == ')' || stack.peek() == '{' && x == '}' || stack.peek() == '[' && x == ']') {
                    stack.pop();
                }else {
                    stack.push(x);
                }
            }
        }
        
        return stack.empty();
    }
}

3)出栈入栈次序匹配:

题析:

题解:

public class Solution {
    public boolean IsPopOrder (int[] pushV, int[] popV) {
        Stack<Integer> stack = new Stack<>();
        int j = 0;
        for(int i = 0; i < pushV.length; i++) {
            stack.push(pushV[i]);
            while(!stack.isEmpty() && j < popV.length && stack.peek() == popV[j]) {
                stack.pop();
                j++;
            }
        }
        if(!stack.isEmpty()) {
            return false;
        }
        return true;
    }
}

2.队列

队列分为单端队列(Queue)和双端队列(Deque),都是接口,都有先入先出,后入后出的特点。

2.1 单端队列(Queue)

(1)特点:

只有一端可以入,一端可以出。Queue可以用线性表(循环队列),也可以用链表(LinkedList)来实现。

(2)方法:

主要的方法就这三种。需要注意的是这里面Queue接口中没有empty()方法,但由于它是继承了Vector类,所以可以使用isEmpty()方法来判断是否Queue为空。

(3)OJ题:

1)设计循环队列:

题析:

题解:

//法一:设置一个计数变量:count
class MyCircularQueue {
    //循环队列的底层就是一个数组
    public int[] arr;
    //队头
    public int front;
    //队尾
    public int tail;
    //计数
    public int count;
    public MyCircularQueue(int k) {
        arr = new int[k];
    }
    
    public boolean enQueue(int value) {
        if(isFull()) {
            //队列已满
            return false;
        }
        if(tail == arr.length) {
            tail = 0;
        }
        arr[tail] = value;
        tail++;
        count++;
        return true;
    }
    
    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        front++;
        if(front == arr.length) {
            front = 0;
        }
        count--;
        return true;
    }
    
    public int Front() {
        if(isEmpty()) {
            return -1;
        }
        return arr[front];
    }
    
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        if(isFull()) {

        }
        int index = (tail == 0) ? 0 : (tail - 1); 
        return arr[index];
    }
    
    public boolean isEmpty() {
        return count == 0;
    }
    
    public boolean isFull() {
        return count == arr.length;
    }
}
//法二:浪费一个空间
class MyCircularQueue {
    //循环队列的底层就是一个数组
    public int[] arr;
    //队头
    public int front;
    //队尾
    public int tail;
    
    public MyCircularQueue(int k) {
        arr = new int[k + 1];
    }
    
    public boolean enQueue(int value) {
        if(isFull()) {
            //队列已满
            return false;
        }
        arr[tail] = value;
        tail = (tail + 1) % arr.length;
        return true;
    }
    
    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        front = (front + 1) % arr.length;
        return true;
    }
    
    public int Front() {
        if(isEmpty()) {
            return -1;
        }
        return arr[front];
    }
    
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        int index = (tail == 0) ? (arr.length - 1) : (tail - 1); 
        return arr[index];
    }
    
    public boolean isEmpty() {
        return tail == front;
    }
    
    public boolean isFull() {
        return (tail + 1) % arr.length == front;
    }
}

浪费一个空间的这种写法: 

题中给的示列:

而按我们这种这里的写法: 如果设置长度为3,那么只能放两个元素,所以需要将数组的长度设置为4就能放三个元素了,也就是数组长度设置为k + 1。

 2.2 双端队列

(1)特点:

两端都可以入队出队。Deque可以用线性表(循环队列),也可以用链表(LinkedList)来实现。

(2)方法:

与单端队列的方法都大同小异。 

3.栈与队列相关的OJ题

(1)用栈实现队列

题析:

题解:

class MyQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    public MyQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }
    public void push(int x) {
        stack1.push(x);
    }
    public int pop() {
        if(stack2.isEmpty()) {
            while(!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
    public int peek() {
        if(stack2.isEmpty()) {
            while(!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }
    public boolean empty() {
        return stack1.isEmpty() && stack2.isEmpty();
    }
}

(2)用队列实现栈:

题析:

题解:

class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    public MyStack() {
        queue1 = new ArrayDeque<>();
        queue2 = new ArrayDeque<>();
    }
    public void push(int x) {
        if(!queue1.isEmpty()) {
            queue1.offer(x);
        }else if(!queue2.isEmpty()) {
            queue2.offer(x);
        }else {
            //两个都为空,指定放在queue1中
            queue1.offer(x);
        }
    }
    public int pop() {
        if(empty()) {
            return -1;
        }
        int i = 0;
        if(!queue1.isEmpty()) {
            int size = queue1.size();
            for(i = 0; i < size- 1; i++) {
                queue2.offer(queue1.poll());
            }
            return queue1.poll();
        }else {
            int size = queue2.size();
            for(i = 0; i < size- 1; i++) {
                queue1.offer(queue2.poll());
            }
            return  queue2.poll();
        }
        
    }
    public int top() {
        int i = 0;
        if(!queue1.isEmpty()) {
            int size = queue1.size();
            int x = -1;
            for(i = 0; i < size; i++) {
                x = queue1.poll();
                queue2.offer(x);
            }
            return x;
        }else {
            int size = queue2.size();
            int x = -1;
            for(i = 0; i < size; i++) {
                x = queue2.poll();
                queue1.offer(x);
            }
            return  x;
        }

    }
    public boolean empty() {
        //两个队列均为空的时候才能判断该栈为空
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp发送Form Data格式请求

设置header的Content-Type为 application/x-www-form-urlencoded 即可 uni.request({url: , // 接口urldata: {input: 写一篇一千字的作文}, // 入参method: POST, // 参数类型header: {"Content-Type": "application/x-www-form-urlencoded"}, // 请求头…

本地部署,isNet 图像背景去除

目录 摘要 引言 ISNet 架构 关键组件 技术原理 本地部署 运行结果 结论 参考文献 GitHub - xuebinqin/DIS: This is the repo for our new project Highly Accurate Dichotomous Image SegmentationThis is the repo for our new project Highly Accurate Dichotomous…

介绍一款数据准实时复制(CDC)中间件 `Debezium`

简介 文章开头先介绍一下什么是CDC。数据准实时复制(CDC)是目前行内实时数据需求大量使用的技术。常用的中间件有Canal、Debezium、Flink CDC等 下面我们做一下对比 各有优缺点吧,本主要介绍一下Debezium中间件。 Debezium是什么 Debezium是一个为变更数据捕获(CDC)提供…

220.贪心算法:根据身高重建队列(力扣)

代码解决 class Solution { public:// 定义排序规则&#xff1a;首先按身高降序排序&#xff0c;如果身高相同则按k值升序排序static bool cmp(const vector<int>&a, const vector<int>&b){if (a[0] b[0]) return a[1] < b[1]; // 如果身高相同&#…

注册自定义总线

1、在/sys/bus下注册一个自定义总线 #include<linux/module.h> #include<linux/init.h> #include<linux/kernel.h> #include<linux/kobject.h> #include<linux/slab.h> #include<linux/sysfs.h> #include<linux/device.h> #include…

【Linux】1w详解如何实现一个简单的shell

目录 实现思路 1. 交互 获取命令行 2. 子串分割 解析命令行 3. 指令的判断 内建命令 4. 普通命令的执行 补充&#xff1a;vim 文本替换 整体代码 重点思考 1.getenv和putenv是什么意思 2.代码extern char **environ; 3.内建命令是什么 4.lastcode WEXITSTATUS(sta…

Java-final关键字详解

Java-final关键字详解 一、引言 二、什么是 final 关键字&#xff1f; 三、final 变量 final 局部变量 final 实例变量 final 静态变量 四、final 方法 五、final 类 六、final 关键字的实际应用 1. 定义常量 2. 防止方法被重写 3. 创建不可变类 4. 优化性能 七、…

GitHub网页打开慢的解决办法

有时候看资料絮叨github网页打不开&#xff0c;经百度后&#xff0c;发下下面的方法有效。 1&#xff09;获取github官网ip 我们首先要获取github官网的ip地址&#xff0c;方法就是打开cmd&#xff0c;然后ping 找到github的地址&#xff1a;20.205.243.166 2&#xff09;配…

数据结构(Java):队列Queue集合力扣面试OJ题

1、队列 1.1 队列的概念 队列是一个特殊的线性表&#xff0c;只允许在一端&#xff08;队尾&#xff09;进行插入数据操作&#xff0c;在另一端&#xff08;对头&#xff09;进行删除数据。队列具有先进先出FIFO(First In First Out)的特性。 入队&#xff1a;数据只能从队尾…

【办公软件】PPT使用轮子动画做圈动作

在实际的PPT制作中&#xff0c;我们可能会用到画圈的动作来强调重点。如下所示为最基础的画圈动作。 那么如何来做一个这样的动作呢&#xff1f; 首先在PPT中选择插入&#xff0c;选择形状椭圆 然后按Shift画图&#xff0c;即可画出一个正圆 然后使用绘图工具&#xff0c;将开关…

程序的控制结构——if-else语句(双分支结构)【互三互三】

目录 &#x1f341; 引言 &#x1f341;if-else语句&#xff08;双分支结构&#xff09; &#x1f449;格式1&#xff1a; &#x1f449;功能&#xff1a; &#x1f449;程序设计风格提示&#xff1a; &#x1f449;例题 &#x1f449;格式2&#xff1a; &#x1f449;…

公司用哪些软件监控员工电脑?五大精选的电脑监控软件盘点

在现代企业管理中&#xff0c;员工电脑监控软件系统成为了不可或缺的工具。这些软件不仅能提高员工工作效率&#xff0c;还能有效保护企业的信息安全。本文将介绍几款主流的员工电脑监控软件系统&#xff0c;帮助企业选择最适合自己的解决方案。固信员工电脑监控软件https://ww…

python1(命名,输入输出,数据类型,与C语言在运算符上的区别)

包名&#xff1a;name_hpy 文件名&#xff1a;name.hpy 对变量命名时不能使用关键字/不能用数字开头/严格区分大小写/不建议使用中文 要在文件中调用关键字时需要输入&#xff1a;import keyword 查看保留字&#xff1a;print&#xff08;keyword.kwlist&#xff09; 查看…

JeecgBoot 前端 vue3 项目,配置项目多页面入口

前端 vue3配置项目多页面入口 1.项目根目录新建home.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><…

树莓派pico入坑笔记,ssd1306使用

目录 关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树莓派pico专栏 说明 后附进阶玩法&#xff1a;显示中文&#xff0c;外加简单库实现 官方模块使用 使用样例 方法说明 下面是绘图支持的方法 进阶玩法&#xff0c;显示中文 方法&#xff0c;对汉字取字模…

STM32的TIM1之PWM互补输出_死区时间和刹车配置

STM32的TIM1之PWM互补输出_死区时间和刹车配置 1、定时器1的PWM输出通道 STM32高级定时器TIM1在用作PWM互补输出时&#xff0c;共有4个输出通道&#xff0c;其中有3个是互补输出通道&#xff0c;如下&#xff1a; 通道1&#xff1a;TIM1_CH1对应PA8引脚,TIM1_CH1N对应PB13引…

HDFS Decommission节点的长尾分析和问题解决

文章目录 前言Decommission过慢的分析过程NameNode页面并不显示Decommission的进度和剩余块数量增加每次调度的块数量增加Stream Limit以避免节点被Skip节点被Skip时应该在DEBUG时打印原因在大量节点被Skip的时候加快有效调度其他可能改进 基本流程解析用户通过节点刷新触发Dec…

怎样在 C 语言中进行结构体的内存布局控制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

【JavaEE】网络原理——网络层+数据链路层

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;上一篇文章&#xff1a;【JavaEE】网络原理—…

RuoYi3.0之sql代码审计

1 SQL注入漏洞代码审计 单点漏洞代码审计首当其冲当然要先看SQL注入漏洞是否存在,全局搜索关键字$,并限定文件类型为.xml,发现sysDeptMapper.xml和sysUserMapper.xml有存在SQL注入的地方,如下图所示: 1.1 SQL注入漏洞代码审计1 单点漏洞代码审计首当其冲当然要先看SQL注…