【数据结构练习题】栈与队列

栈与队列

  • 选择题
  • 括号匹配
  • 逆波兰表达式求值
  • 出栈入栈次序匹配
  • 最小栈
  • 设计循环队列
  • 面试题
    • 1. 用队列实现栈。[OJ链接](https://leetcode.cn/problems/implement-stack-using-queues/solutions/)
    • 2. 用栈实现队列。[OJ链接](https://leetcode.cn/problems/implement-queue-using-stacks/description/)

选择题

在这里插入图片描述

用无头单链表存储队列,front引用队头,back引用队尾,则在进行出队列操作时( )
A.仅修改front
B.front 和 back 都要修改
C.front 和 back 可能都要修改
D.仅修改back

出队列时:
如果队列中有多个节点时,只需要修改front
如果队列中只有一个节点时,front和back都需要修改
故应该选择C

下列关于队列的叙述错误的是( )
A.队列可以使用链表实现
B.队列是一种"先入先出"的数据结构
C.数据出队列时一定只影响队尾引用
D.数据入队列时一定从尾部插入

A正确:队列是尾插头删,就适合使用链表实现
B正确:队列的特性
C错误:如果队列中只有一个元素时,出队列后队尾和队头引用都会影响
D正确:队列的特性
故选择C

*4.下列关于用栈实现队列的说法中错误的是( )
A.用栈模拟实现队列可以使用两个栈,一个栈模拟入队列,一个栈模拟出队列
B.每次出队列时,都需要将一个栈中的全部元素导入到另一个栈中,然后出栈即可
C.入队列时,将元素直接往模拟入队列的栈中存放即可
D.入队列操作时间复杂度为O(1)

答案:B
选项B中,一个栈模拟入队列,一个栈模拟出队列,出队列时直接弹出模拟出队列栈的栈顶元素,当该栈为空时,将模拟入队列栈中所有元素导入即可,不是每次都需要导入元素,故错误
选项A中,栈和队列的特性是相反的,一个栈实现不了队列
选项C中,一个栈模拟入队列,一个栈模拟出队列,入队列时,将元素直接往模拟入队列的栈中存放
选项D中,入队列就是将元素放到栈中,因此时间复杂度就是O(1)

以下不是队列的基本运算的是( )
A.从队尾插入一个新元素
B.从队列中删除队尾元素
C.判断一个队列是否为空
D.读取队头元素的值

答案:B
解析:
队列只能从队头删除元素。

下面关于栈和队列的说法中错误的是( )
A.队列和栈通常都使用链表实现
B.队列和栈都只能从两端插入、删除数据
C.队列和栈都不支持随机访问和随机插入
D.队列是“先入先出”,栈是“先入后出”

A错误:栈是尾部插入和删除,一般使用顺序表实现,队列是头部删除尾部插入,一般使用链表实现
B错误:栈是后进先出,尾部插入和删除;队列是先进先出,尾部插入头部删除
C正确:栈只能访问栈顶元素,不支持随机访问,队列也不支持
D正确:栈和队列的特性
故错误的是A和B

9.下列关于顺序结构实现循环队列的说法,正确的是( )
A.循环队列的长度通常都不固定
B.直接用队头和队尾在同一个位置可以判断循环队列是否为满
C.通过设置计数的方式可以判断队列空或者满
D.循环队列是一种非线性数据结构

队列适合使用链表实现,使用顺序结构(即固定的连续空间)实现时会出现假溢出的问题,因此大佬们设计出了循环队列,循环队列就是为了解决顺序结构实现队列假溢出问题的
A错误:循环队列的长度都是固定的
B错误:队头和队尾在同一个位置时 队列可能是空的,也可能是满的,因此无法判断
C正确:设置计数即添加一个字段来记录队列中有效元素的个数,如果队列中有效元素个数等于空间总大小时队列满,如果队列中有效元素个数为0时队列空
D错误:循环队列也是队列的一种,是一种特殊的线性数据结构
故选择C

现有一循环队列,其队头为front,队尾为rear(rear指向队尾数据的下一个位置),循环队列长度为N,最多存储N-1个数据。其队内有效长度为( )
A.(rear - front + N) % N + 1
B.(rear - front + N) % N
C.(rear - front) % (N + 1)
D.(rear - front + N) % (N - 1)

答案:B
有效长度一般是rear-front, 但是循环队列中rear有可能小于front,减完之后可能是负数,所以需要+N,此时结果刚好是队列中有效元素个数,但如果rear大于front,减完之后就是有效元素个数了,再加N后有效长度会超过N,故需要%N。

下述有关栈和队列的区别,说法错误的是?
A.栈是限定只能在表的一端进行插入和删除操作。
B.队列是限定只能在表的一端进行插入和在另一端进行删除操作。
C.栈和队列都属于线性表
D.栈的插入操作时间复杂度都是o(1),队列的插入操作时间复杂度是o(n)

A正确:参考栈的概念
B正确:参考队列的概念
C正确:栈和队列都是特殊的线性表,因为线性表可以在任意位置插入或者删除,但是栈和队列就没有,相当于栈和队列属于阉割版的线性表
D错误:栈和队列插入、删除操作的时间复杂度都是O(1)
故选择D

括号匹配

括号匹配
在这里插入图片描述
只要是左括号 就入栈
遇到右括号 就开始匹配
1.和栈顶不匹配
2.栈为空
3.栈不为空 但是字符串遍历完了

class Solution {
    public boolean isValid(String s) {
        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.empty()){
                    return false;
                }
                char top=stack.peek();
                if(top=='('&&ch==')'||top=='['&&ch==']'||top=='{'&&ch=='}'){
                    stack.pop();
                }else{
                    return false;
                }
            }
        }
        if(!stack.empty()){
            return false;
        }
        return true;
    }
}

逆波兰表达式求值

逆波兰表达式求值

后缀表达式也叫逆波兰表达式
在这里插入图片描述
在这里插入图片描述

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack=new Stack<>();
        for(String s:tokens){
            if(!isOperation(s)){
                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();
    }
    public boolean isOperation(String s){
        if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/"))
            return true;
        return false;
    }
}

出栈入栈次序匹配

出栈入栈次序匹配

import java.util.*;

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.empty()&&j<popV.length&&stack.peek()==popV[j]){
                stack.pop();
                j++;
            }
        }
        return stack.empty();
    }
}

最小栈

最小栈
在这里插入图片描述

class MinStack {
    private Stack<Integer> stack;
    private Stack<Integer> minstack;
    public MinStack() {
        stack=new Stack<>();
        minstack=new Stack<>();
    }
    
    public void push(int val) {
        stack.push(val);
        if(minstack.empty()){
            minstack.push(val);
        }else{  //=要加上,否则stack中此数有多个 出栈时minstack也要出栈 数不够只有一个
            if(val<=minstack.peek()){
                minstack.push(val);
            }
        }
    }
   
    public void pop() {
        if(!stack.empty()){
            int ret=stack.pop();
            if(minstack.peek()==ret){
                minstack.pop();
            }
        }
    }
     //获取正常栈顶元素
    public int top() {
        if(stack.empty()){
            return -1; //oj题中轻易不要抛出异常 直接return-1即可
        }
        return stack.peek();
    }
    //获取最小栈顶元素
    public int getMin() {
        if(minstack.empty()){
            return -1;
        }
        return minstack.peek();
    }
}

设计循环队列

设计循环队列

/*
    解题思路:
    1. 注意,循环队列底层空间大小是固定的
    2. 采用计数方式实现队列空或者满的判断
    3. 入队列时:队列可能满,往队尾插入,注意back在末尾特殊情况
    4. 出队列时:队列可能空,删除队头元素,注意front可能在队尾
    5. 获取队头注意空队列时返回-1
    6. 获取队尾时,注意back-1可能为负数,队尾元素下标:
       (back-1+array.length)%array.length
*/
class MyCircularQueue {
    int[] array;
    int front;   // 队头
    int back;    // 队尾
    int count;   // 队列中有效元素个数
    public MyCircularQueue(int k) {
        array = new int[k];
    }
    
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }

        // 在队尾插入一个元素,然后back往后移动
        array[back] = value;
        back++;

        // back往后移动之后,可能会来到空间末尾
        // 此时将back挪到空间起始位置
        if(back == array.length){
            back = 0;
        }

        count++;
        return true;
    }
    
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }

        // 出队列,队头往后移动
        ++front;

        // 队头往后移动之后也可能会来到空间末尾
        // 此时需要挪到空间起始位置
        front %= array.length;
        --count;
        return true;
    }
    
    public int Front() {
        if(isEmpty()){
            return -1;
        }

        // 如果队列不空,说明队列中有元素,队头元素直接返回front即可
        return array[front];
    }
    
    public int Rear() {
        if(isEmpty()){
            return -1;
        }

        // 如果队列不空,说明队列中有元素
        // 队尾元素即:back-1,
        // 如果back不在0号位置,back-1就是队尾元素下标
        // 如果back在0号位置,-1之后就是负数,因此需要+数组长度
        // 两个结合起来:
        return array[(back - 1 + array.length)%array.length];
    }
    
    public boolean isEmpty() {
        return 0 == count;
    }
    
    public boolean isFull() {
        return count == array.length;
    }
}


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

面试题

1. 用队列实现栈。OJ链接

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:pop容易错写成下图 que.size是变量 会随着循环改变 应该提前记录一下que.size
在这里插入图片描述

/*
   解题思路:
     借助两个队列来模拟实现栈。一个队列是辅助的,起到导元素的作用
     入栈:
       先将元素放入a队列中,如果b不空,将b中所有元素导入到a中
       此时,刚刚入栈的元素刚好在a的队头,然后将a和b队列交换下
       即:b队列队头相当于栈顶,b队列队尾相当于栈底
     出栈:
       直接从b中poll()即可
     获取栈顶元素:
       直接从b中peek()即可
 */
class MyStack {
    private Queue<Integer> a;  // a是用来辅助导元素的
    private Queue<Integer> b;  // 元素全部放在b中
    public MyStack() {
        a = new LinkedList<>();
        b = new LinkedList<>();
    }
    
    public void push(int x) {
        // 先把元素放入a队列中
        a.offer(x);

        while(!b.isEmpty()){
            a.offer(b.poll());
        }

        Queue<Integer> temp = a;
        a = b;
        b = temp;
    }
    
    public int pop() {
        return b.poll();
    }
    
    public int top() {
        return b.peek();
    }
    
    public boolean empty() {
        return b.isEmpty();
    }
}

2. 用栈实现队列。OJ链接

/*
    解题思路:
     利用两个栈模拟实现队列
     入队列:s1模拟入队列,所有入队列的元素都放入到s1中
     出队列:s2模拟出队列,当s2为空时,将s1中所有元素导入到s2中
            s2中pop一个元素
     获取队头元素:如果s2是空,将s1中所有元素导入s2中,然后peek()一个元素
 */
class MyQueue {
    private Stack<Integer> s1;  // 模拟入队列,所有元素都放入到s1中
    private Stack<Integer> s2;
    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    
    // 入队类时,直接找s1
    public void push(int x) {
        s1.push(x);
    }
    
    // 出队列:如果s2是空的,需要将s1中的所有元素导入到s2中
    // 此时s1先压入的元素就后进入到s2中,出的时候就先出了
    public int pop() {
        if(s2.empty()){
            while(!s1.empty()){
                s2.push(s1.pop());
            }
        }
        return s2.pop();
    }
    
    public int peek() {
        if(s2.empty()){
            while(!s1.empty()){
                s2.push(s1.pop());
            }
        }
        return s2.peek();
    }
    
    public boolean empty() {
        return s1.empty() && s2.empty();
    }
}

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

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

相关文章

python 定时任务管理封装

主逻辑代码 # -*- coding: utf-8 -*- # import apscheduler import pandas as pd from datetime import datetime # 导入调度器&#xff0c;此处使用BackgroundScheduler阻塞调度器 from apscheduler.schedulers.background import BackgroundScheduler # 导入触发器&#xf…

MaxKB基于大语言模型和 RAG的开源知识库问答系统的快速部署教程

1 部署要求 1.1 服务器配置 部署服务器要求&#xff1a; 操作系统&#xff1a;Ubuntu 22.04 / CentOS 7.6 64 位系统CPU/内存&#xff1a;4C/8GB 以上磁盘空间&#xff1a;100GB 1.2 端口要求 在线部署MaxKB需要开通的访问端口说明如下&#xff1a; 端口作用说明22SSH安装…

LCAN-FOBR设备在风力发电项目的消防通讯中的使用

LCAN-FOBR设备在风力发电项目的消防通讯中的使用 在风力发电项目中&#xff0c;所有的风机内部的状态都需要能够在中控室备被监控到&#xff0c;不论是风机的工作状态还是风机内部的消防状态&#xff0c;以便中控室的工作人员都够根据观测到的信息及时的做出反应&#xff0c;避…

Linux扩展——shell编程

前置&#xff1a;Linux基础及命令复习 目录 shell概述Shell脚本入门案例 sh bash ./ . source 变量系统预定义变量 $HOME $PWD $SHELL等自定义变量 unset readonly补充&#xff1a;开启子Shell进程的常见方法 (...) $(...) ... <(...) >(...) 特殊变量 $n $# $* $ $&…

计算机网络-GRE Over IPSec实验

一、概述 前情回顾&#xff1a;上次基于IPsec VPN的主模式进行了基础实验&#xff0c;但是很多高级特性没有涉及&#xff0c;如ike v2、不同传输模式、DPD检测、路由方式引入路由、野蛮模式等等&#xff0c;以后继续学习吧。 前面我们已经学习了GRE可以基于隧道口实现分支互联&…

【运维笔记】向日葵远程:输入法大写无法切换至小写

项目场景&#xff1a; 向日葵&#xff1a;远程客户电脑ubuntu系统 客户电脑&#xff1a;windows 10 &#xff0c;并安装向日葵 服务器&#xff1a;ubuntu系统 问题描述 维护ubuntu时突然无法切换成小写&#xff0c;导致无法运维 原因分析&#xff1a; 大写键被锁住 解决方案…

「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件

本篇将带你实现一个自定义天气预报组件。用户可以通过选择不同城市来获取相应的天气信息&#xff0c;页面会显示当前城市的天气图标、温度及天气描述。这一功能适合用于动态展示天气信息的小型应用。 关键词 UI互动应用天气预报数据绑定动态展示状态管理 一、功能说明 自定义…

AAAI-2024 | 大语言模型赋能导航决策!NavGPT:基于大模型显式推理的视觉语言导航

作者&#xff1a;Gengze Zhou, Yicong Hong, Qi Wu 单位&#xff1a;阿德莱德大学&#xff0c;澳大利亚国立大学 论文链接&#xff1a; NavGPT: Explicit Reasoning in Vision-and-Language Navigation with Large Language Models &#xff08;https://ojs.aaai.org/index.p…

react杂乱笔记(一)

程序“npx”无法运行: 找不到应用程序所在位置 行:1 字符: 1 解决方法; 不要在vscode中执行命令,在cmd 中可以执行 Module not found: Error: Cant resolve web-vitals in D:\learn\react-basic\src ERROR in ./src/reportWebVitals.js 5:4-24 Module not found: Error: Cant…

【计算机视觉】opencv-停车位检测原理及代码演示

概述 本文介绍了一种基于OpenCV库的停车场空位检测方法。通过本项目演示&#xff0c;可以对opencv库有更深刻的理解。文章详细阐述了检测原理、算法流程以及代码实现。 一、原理介绍 基于OpenCV的停车位检测原理涉及多个图像处理步骤&#xff0c;以下将结合相关公式详细介绍每…

华为认证考试模拟题测试题库(含答案解析)

你还在为华为认证数通考试的备考而烦恼吗&#xff1f; 还在纠结如何高效复习&#xff0c;掌握考点吗&#xff1f; 腾科IT教育为广大考生提供了华为认证考试模拟题库&#xff0c;让你在考试前轻松应对各种题型&#xff0c;提升做题能力与考试信心&#xff01; 【单选题】 PPP…

序列化和反序列化(一)

因为通过这段时间的学习&#xff0c;发现&#xff0c;序列化和反序列化的考点和漏洞在平时遇到的还是比较多的&#xff0c;而且自己也没有特别去学习过这个知识点&#xff0c;所以在这里写一篇关于这里序列化和反序列话的博客&#xff0c;废话就停止在这里了。 在介绍具体的序列…

优雅草央千澈-关于蓝湖如何快速的标注交互原型是如何使用的-如何使用蓝湖设计交互原型和整个软件项目的流程逻辑-实践项目详细说明

优雅草央千澈-关于蓝湖如何快速的标注交互原型是如何使用的-如何使用蓝湖设计交互原型和整个软件项目的流程逻辑-实践项目详细说明 问题背景 我们ui设计师在设计完整套ui的时候一般要标注原型&#xff0c;但是如果ui对项目整体理解不够深刻的时候&#xff0c;一般就产品经理需要…

三维测量与建模笔记 - 7.3 表面建模概念和方法

基本概念 当我们通过3D扫描设备对物体进行扫描后&#xff0c;会得到三维点云&#xff0c;通过表面建模&#xff0c;我们会重建出物体的3D模型。如果想得到完整的物体的3D模型&#xff0c;需要对物体进行多个角度的扫描并通过拼接算法重建。经过处理得到的3D模型&#xff0c;在很…

共模电感的工作原理

共模电感也称为共模扼流线圈&#xff0c;是一种抑制共模干扰的器件&#xff0c;它是由两个尺寸相同&#xff0c;匝数相同的线圈对称地绕制在同一个铁氧体环形磁芯上&#xff0c;形成的一个四端器件。当共模电流流过共模电感时&#xff0c;磁芯上的两个线圈产生的磁通相互叠加&a…

汉塔科技-上网行为管理系统 ping.php 远程命令执行漏洞复现

0x01 产品简介 汉塔科技是一家专注于网络应用软件开发的公司,在网络安全、网络协议分析以及网络数据流控制等领域拥有丰富的经验和雄厚的技术实力。其上网行为管理系统是应用识别丰富、网络安全防护强大的专业设备之一,汉塔科技上网行为管理系统是一款功能强大、应用识别丰富…

图书管理系统5,制作第十天

1. 在Java中&#xff0c;BigDecimal 类提供了多种方法可以用来将其转换为 String 类型。以下是几种常见的方法&#xff1a; 使用 toString() 方法&#xff1a; 这是将 BigDecimal 转换为 String 的最直接的方法。 Java 深色版本 BigDecimal bd new BigDecimal("123.456&…

机器视觉检测相机基础知识 | 颜色 | 光源 | 镜头 | 分辨率 / 精度 / 公差

注&#xff1a;本文为 “keyence 视觉沙龙中机器视觉检测基础知识” 文章合辑。 机器视觉检测基础知识&#xff08;一&#xff09;颜色篇 视觉检测硬件构成的基本部分包括&#xff1a;处理器、相机、镜头、光源。 其中&#xff0c;和光源相关的最重要的两个参数就是光源颜色和…

Linux shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件

Linux Debian12基于ImageMagick图像处理工具编写shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件&#xff0c;”多个图片分开生成多个PDF文件“或者“多个图片合并生成一个PDF文件” 在Linux系统中&#xff0c;使用ImageMagick可以图片格式转换&#xff0c…

批量提取zotero的论文构建知识库做问答的大模型(可选)——含转存PDF-分割统计PDF等

文章目录 提取zotero的PDF上传到AI平台保留文件名代码分成20个PDF视频讲解 提取zotero的PDF 右键查看目录 发现目录为 C:\Users\89735\Zotero\storage 写代码: 扫描路径‘C:\Users\89735\Zotero\storage’下面的所有PDF文件,全部复制一份汇总到"C:\Users\89735\Downl…