栈和队列以及简单应用

兰理鲲鹏-C语言简单的【栈和队列】(括号匹配问题) 栈和队列轻松搞定 阅读详情

栈和队列

栈的概念和实现

栈的概念

栈是一种特殊的线性表,它只允许在其固定的一端进行插入和删除操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的元素遵循先入后出的规则。
栈的插入也叫入栈、压栈、进栈。是将入栈元素存放在栈顶,栈顶元素变更为新存放的元素。
栈的删除也叫出栈。是将栈顶元素删除。栈顶元素变为删除后的栈顶元素的下一个元素。

栈的基本操作

栈的操作一般常用的为初始化,入栈,出栈,获取栈顶元素,判断栈是否为空,判断栈是否已满。这些操作代码将会在栈的实现中出现。

用链表和顺序表实现栈

栈的实现主要可以靠顺序表或者链表来实现。但是由于是在队尾操作,所以根据顺序表和链表的特性,一般顺序表实现比较简单。

顺序表实现栈
import java.util.Arrays;

public class MyStack {
//顺序表的底层是数组,因此使用数组来存储栈元素;
    public int [] elem;
    public int top;//用来获取栈的长度,防止数组越界异常。

    public MyStack(){//构造栈
        elem = new int [10];
        top = 0;
    }

    public boolean isFull(){//判满
        if(top == elem.length){
            return true;
        }else{
            return false;
        }
    }
    public void push(int val){//入栈操作
        if(isFull()){//扩容
            Arrays.copyOf(elem , elem.length * 2);
        }
        elem[top] = val;
        top++;
    }

    public int pop() {//出栈
        if(empty()){
            return -1;
        }
        int ret = elem[top - 1];
        top--;
        return ret;
    }

    public boolean empty(){//判空
        if(top == 0){
            return true;
        }else{
            return false;
        }
    }

    public int peek(){//获取栈顶元素
        if(empty()){
            return -1;
        }
        return this.elem[this.top - 1];
    }
}
链表实现栈
class StackNode{
    public int value;//存放的数据
    public StackNode next;//指向下一个节点
    public StackNode(int val){//构造函数
        value = val;
    }
}
public class MyStack {
    public StackNode front;
    public StackNode rear;
    public int usedSize = 0;

    public void push(int num){//入栈
        StackNode stackNode = new StackNode(num);
        if(front == null){
            front = stackNode;
            rear = stackNode;
        }else{
            rear.next = stackNode;
            rear = stackNode;
        }
        usedSize++;
    }

    public int pop(){//出栈
        if(empty()){
            return -1;
        }
        int ret = rear.value;
        if(usedSize == 1){
            front = null;
            rear = null;
        }else{
            StackNode cur = front;
            int num = 1;
            while(num != (usedSize - 1)) {
                cur = cur.next;
                num++;
            }
            rear = cur;
            rear.next = null;
            usedSize--;
        }
        return ret;
    }

    public boolean empty(){//判空
        return front == null;
        //return usedSize == 0;
    }
    
    public int peek(){//获取栈顶元素
        if(empty()){
            return -1;
        }
        return rear.value;
    }
实现最小栈

通过栈来获取数据中的最小值。

import java.util.Stack;
public class MinStack {
	public Stack<Integer> stack;
    public 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 {
            int num = minStack.peek();
            if(val <= num){
                minStack.push(val);
            }
        }
    }
    //出栈
    public void pop(){
    	if(minStack.isEmpty()){
            return;
        }
        int num = stack.pop();
        int min = minStack.peek();
        if(num == min){
            minStack.pop();
        }
    }
	//普通栈顶元素
	public int top(){
		if(stack.empty()){
            return -1;
        }
        return stack.peek();
    }
	//最小栈顶元素
	public int getMin(){
        if(minStack.empty()){
            return -1;
        }
        return minStack.peek();
    }
}

队列的概念与实现

队列的概念

队列是只允许在一端插入数据而在另一端进行删除数据的一种特殊线性表,队列遵循着先入先出的规则。
其中入队列是进行数据插入的操作,这一端称为队尾。
出队列是进行数据删除的操作,这一端称为队头。

队列的基本操作

队列的基本操作一般有入队列,出队列,判断队列是否为空,获取队首元素。这些代码在队列的实现中展示。

队列的实现

队列的实现也可以用顺序表和链表来进行实现,但是由于是两端操作,所以根据顺序表和链表的特性,一般链表实现比较简单。

链表实现队列
class QueueNode{
    public int value;//节点存放的数据
    public QueueNode next;//指向下一个节点

    public QueueNode(int val){//构造函数
        this.value = val;
    }
}

public class MyQueue {

    public QueueNode front;//头
    public QueueNode rear; //尾
    public int usedSide;

    //入队列
    public void offer(int value){
        QueueNode queueNode = new QueueNode(value);
        if(this.front == null){
            this.front = queueNode;
            this.rear = queueNode;
        }else {
            this.rear.next = queueNode;
            this.rear = queueNode;
        }
        this.useSide++;
    }

    //出队
    public int poll(){
        if(this.isEmpty()){
            return -1;
        }
        int ret = this.front.value;
        this.front = this.front.next;
        this.useSide--;
        return ret;

    }

    public boolean isEmpty(){
        return this.front == null;
    }

    //获取队首元素
    public int peek(){
        if(this.isEmpty()){
            return -1;
        }
        return this.front.value;
    }

    public int size(){
        return this.useSide;
    }
}
顺序表实现队列
import java.util.Arrays;

public class MyQueue {
    public int [] arr;
    public int len;
    public int top;

    public MyQueue(){
        arr = new int[10];
        len = 0;
        top = 0;
    }
    
	//判满
    public boolean isFull(){
        if(len == arr.length){
            return true;
        }else{
            return false;
        }
    }
    
	//入队列
    public void offer(int value){
        if(isFull()){//满了扩容
            Arrays.copyOf(arr , arr.length * 2);
        }
        arr[len++] = value;
    }
    
	//判空
    public boolean isEmpty(){
        if(top == len){
            return true;
        }else{
            return false;
        }
    }

	//出队列
    public int poll(){
        if(isEmpty()){
            return -1;
        }
        int ret = arr[top];
        arr[top++] = 0;
        return ret;
    }
    
	//获取队首元素
    public int peek(){
        if(isEmpty()){
            return -1;
        }
        return arr[top];
    }

	//队列长度
    public int size(){
        return len - top;
    }
}
循环队列及实现

循环队列就是将队列变成一个环状,在上述的数组实现队列时,队列大量的进行删除操作会造成队首元素后移,从而造成数组0下标到队列队首下标之间的浪费,而循环链表就可以解决这种资源浪费。但循环队列的缺点是它的队列长度给定了,无法在进行扩容,因此在使用时需要提前判断数据的大小来给定队列的大小。

public class MyCircularQueue {
    public int [] elem;
    public int front;
    public int rear;

//虽然给定的队列长度是k,但是由于有进行队尾元素的操作和判断,
//所以真正的队列长度为k+1.
    public MyCircularQueue(int k){
        elem = new int[k + 1];
    }

    //入队
    public boolean enQueue(int value){
        if(isFull()){
            return false;
        }
        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        return true;
    }

    //出队
    public boolean deQueue(){
        if(isEmpty()){
            return false;
        }
        front = (rear + 1) % elem.length;
        return true;
    }

    public int Front(){//获得队首元素
       if(isEmpty()){
           return -1;
       }
       return elem[front];
    }

    public int Rear(){//获得队尾元素
        if(isEmpty()) {
            return -1;
        }
        if(rear == 0){
            return elem[elem.length - 1];
        }
        return elem[rear - 1];
    }

    public boolean isEmpty(){//判断队列是否为空
        return front == rear;
    }

    public boolean isFull(){//判断队列是否存满
        //判断rear的下一个是不是front
        if((rear + 1) % elem.length == front){
            return true;
        }
        return false;
    }

    //打印
    public void display(){
        for(int i = 0 ; i < elem.length - 1 ; i++){
            System.out.print(elem[i]);
        }
        System.out.println();
    }

}
双端队列

双端队列是指两端都能进行入队和出队的操作的队列,那就说明元素可以从队首入队和出队,也能从队尾进行入队和出队。它的代码和普通队列类似,只需要增加堆首入队和队尾出队方法就可实现。

栈和队列的相互转换

用栈实现队列

class MyQueue {
    public Stack<Integer> stack1;
    public 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() {
        int num = 0;
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                num = stack1.pop();
                stack2.push(num);
            }
        }
        return stack2.peek();
    }
    
    //判空
    public boolean empty() {
        return stack1.isEmpty() && stack2.isEmpty();
    }
}

用队列实现栈

class MyStack {
    public Queue<Integer> queue1;
    public Queue<Integer> queue2;

    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    //入栈
    public void push(int x) {
        queue2.offer(x);
        while(!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        Queue<Integer> tmp = queue1;
        queue1 = queue2;
        queue2 = tmp;//经过两个队列的交换,queue1最后的顺序变为栈操作的顺序
    }
    
    //出栈
    public int pop() {
        return queue1.poll();
        
    }
    
    //查看栈顶元素
    public int top() {
        return queue1.peek();
    }
    
    //判空
    public boolean empty() {
        return queue1.isEmpty();
    }
}
ROS 2在自动驾驶中的应用:感知节点开发 ROS 2在自动驾驶中的应用:感知节点开发 ,人工智能,计算机视觉,大模型,AI,本文围绕ROS 2在自动驾驶感知节点开发展开,介绍了ROS 2基础、感知节点开发流程,包括环境搭建、代码编写等,还阐述了常用传感器感知节点开发、多传感器融合,以及测试调试、性能优化、部署集成等内容,分析了开发面临的挑战与未来趋势,为相关开发提供了全面指导,涉及简单代码示例和概念解释。 阅读详情

相关推荐

R语言实战:非正态数据下的Scheirer–Ray–Hare检验全流程解析

本文详细解析了在R语言中执行Scheirer–Ray–Hare检验的全流程。当数据不满足正态分布假设时,该非参数检验是传统双因素方差分析的有效替代方案。文章从原理、R环境配置、数据准备、代码实现、结果解读到事后比较与可视化,提供了完整的实战指南,帮助研究者稳健地分析多因素实验设计中的主效应和交互效应。

cc789的博客 406

栈和队列的实际运用场景

在浏览网页时,每次访问一个新页面时,当前页面的信息将被推入栈中。当用户点击后退按钮时,程序将从栈中弹出最近的访问页面,并显示上一个页面。每当用户执行一个操作时,比如添加、删除或修改,相关信息将被推入栈中。当用户选择撤销时,程序将从栈中弹出最近的操作并还原到上一个状态。在递归函数中,每次递归调用时,函数的当前状态(包括参数和局部变量)会被推入栈中。当有新的消息需要发送时,它们将排队在队列中,然后按照先进先出的顺序逐个发送。该算法通过逐层遍历图中的节点,并使用队列来存储待访问的节点,从而实现对整个图的搜索。

m0_60480690的博客 4667

Mac新手必看:为什么你的终端找不到Python命令?5分钟搞定zsh报错

本文针对Mac用户在终端遇到“zsh: command not found: python”报错的问题,提供了深度解析与实战修复指南。文章解释了macOS系统因历史原因默认使用`python3`而非`python`命令,并详细介绍了四种解决方案:养成使用`python3`的习惯、创建别名、通过Homebrew安装链接以及修改PATH环境变量,帮助新手快速解决zsh报错,顺利开始Python开发。

weixin_29248653的博客 594

堆栈和队列

开发工具与关键技术:VS, ASP.NET MVC 作者:谭威 撰写时间:2019年05月05日 在生活中,我们将堆栈进出的顺序想象为洗碗,我们洗完的第一只碗我们通常都会放到最下面,第二只会放在第一只的上面,依次类堆,当我们想要拿出来时,我们却拿不到第一只,因为第一只已经被其它的压住了,所以我们只能拿起最后的那一只。从这里我们可以看到堆栈的特点就是后进先出。堆栈简称为栈,是限定只能在表的一端进行插...

qq_44538246的博客 293

别再折腾老教程了!树莓派4B/5最新系统(Raspberry Pi OS Bookworm)红外遥控配置,用gpio-ir驱动一次成功

本文详细介绍了树莓派4B/5在最新Raspberry Pi OS Bookworm系统下配置红外遥控的完整指南,摒弃过时的lirc-rpi驱动,采用现代gpio-ir驱动方案。从硬件连接到软件配置,提供10分钟快速上手指南,涵盖驱动加载、信号测试、按键映射及高级应用场景,帮助用户高效完成红外遥控配置。

weixin_42520909的博客 442

csp-j/s

CSP-J/S 是中国计算机学会(CCF)主办的 ‌‌(Certified Software Professional Junior/Senior),是信息学奥赛(NOI)体系的入门级选拔考试,也是国内最具权威性的青少年编程能力认证之一。

gxyxxrYYDS的博客 2028

堆栈队列实例

堆栈:先进后出 队列:先进先出 日常生活中队列很常见。还有什么堆栈的典型例子? 夏天逛超市时,你可能会忍不住想喝一瓶冰饮料降降温。 可是,困扰你的是:放冰箱外头的饮料往往并不冰,而冰箱深处你够不着的地方,才是你想要的。 想想看:冰箱中的饮料应该组织成“队列”还是“堆栈”?你对超市中的冰箱设计有什么改进性的建议? 比如交试卷,假设学生交试卷的方向都统一,且后来的学生都放在

acmsongye的博客 6728

CloudCompare 二次开发(36)——非均匀体素降采样

使用CloudCompare与PCL编程实现的非均匀体素降采样。

点云侠的博客 746

数据结构(19)栈和队列的实际应用

1、栈在括号匹配中的应用 假设表达式中允许两种括号:圆括号和方括号,其嵌套的顺序任意即([]())或[([][])]等均为正确的格式,[(])这种交叉的为不正确的格式。 考虑下面括号序列: [ ( [ ] [ ] ) ] 1 2 3 4 5 6 7 8 分析如下: 1)计算机接收第一个“[”后,期待与之匹配的第8个括号“]”出现。 2)获得了第2个括号“(”,此时第一个括号“[”暂时放在一边,而几波期待与之匹配的第7个括...

李白 7867

大模型系列——Ollama-OCR 简明教程

Llama 3.2-Vision 是一个多模态大型语言模型,有 11B 和 90B 两种大小,能够处理文本和图像输入以生成文本输出。该模型在视觉识别、图像推理、图像描述和回答与图像相关的问题方面表现出色,在多个行业基准测试中优于现有的开源和闭源多模态模型。在本文中,我将介绍如何调用由 Ollama 运行的 Llama 3.2-Vision 11B 建模服务并使用实现图像文本识别 (OCR) 功能。

2401_84052244的博客 1万+

PHM2010刀具磨损预测完整实现

本文介绍了PHM2010刀具磨损预测项目的完整实现方案。项目采用PHM2010公开数据集,包含6个子数据集,记录了铣削加工过程中7个通道的传感器数据(切削力、振动和声发射信号)。技术路线包括数据预处理(截取中间10万点、小波降噪)、特征提取(时域9个、频域4个特征)、特征融合和皮尔逊相关系数筛选,最终使用BiLSTM模型进行训练和评估。环境配置基于Python 3.9,依赖NumPy、Pandas、PyTorch等库。数据加载和预处理阶段重点处理了传感器信号分段和磨损标签对齐问题,为后续建模奠定基础。

huanghm88的专栏 420

栈和队列的操作和应用

本节内容 、 1.栈和队列的特性 栈:后进先出 •栈:受限制的线性表,只允许从表的一端操作。这端称为栈顶,另一端为栈底 •压入元素(push):往栈顶新增一个元素,新元素成为新栈顶。 •弹出元素(pop):移除栈顶元素,原栈顶的元素成为新栈顶/或栈变成空栈 •图片表示进出栈结果: *key1:栈是一种先进后出的数据结构,pop和push操作仅在栈顶进行 队列:先进先出 •队列:受限制的线性表,只允许从表的两端操作,一端是队首,一端是队尾。 •入队(enqueue)...

sinat_58088248的博客 4416

资源分享·病毒样本下载资源分享

一、微步云沙箱 微步在线云沙箱https://s.threatbook.cn/ 使用病毒sha256即可寻找病毒样本;该站点也可上传可疑文件/可疑URL地址到沙箱中,进行分析 。 以永恒之蓝为例,样本sha256是:ed01ebfbc9eb5bbea545af4d01bf5f1071661840480439c6e5babe8e080e41aa 下载样本或流量监控,需要消耗积分: 二、AnyRun Interactive Online Malware Analysis Sandbox.

不忘初心,护天下安全! 2万+

【栈和队列】C语言简单应用 ⌊栈和队列互相实现,循环队列⌉

栈和队列简单应用

qq_62852431的博客 2299

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

一文了解栈和队列的简单应用

栈和队列的简单应用

weixin_73681410的博客 1143

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

栈和队列的简单应用

回文检测 把一个序列分别放入栈和队列中,根据二者不同的性质,栈会输出一个相反的队列,比较二者输出是否相同,就可以判断该序列是否是回文 括号匹配 如图所示,遍历序列,把右边括号“)” “]”出现之前的左边括号“[” ,"("全部入栈入栈  出现第一个右边继续遍历,出现第一个右边括号时,弹栈,看括号类型是否匹配 直到这个序列访问结束。

雪村一郎的博客 629

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

栈和队列存储结构及简单应用

一、栈和队列的基本介绍 1.栈--先进后出 2.队列--先进先出 二、顺序栈队列(c语言)的完整实现 1.代码部分 2.解说部分 三、顺序栈(c语言)的代码实现 四、简单应用 1.四则运算计算器 完整代码实现(c++): 2.括号配对问题

yanlin01的博客 996

栈和队列的简单应用(菜鸟营)

栈和队列的简单应用(在二叉树中) 以前写过栈和队列使用C实现的帖子,不过以后的使用我打算使用C++,虽然实现起来C++和C区别还不算十分的大,但是C++在表达逻辑的角度要比C使用的工具更加广泛。 我们先介绍一种问题,函数的调用问题。我们知道函数可以实现递归调用,而且在思路上,递归调用非常的香。但是递归调用有一个很大的问题,就是调用函数会花费额外的时间开销。如果一直使用递归解决问题,会在函数调用上花费大量的时间。所以,我们剖析本质,看看递归到底是什么过程,能不能换成非递归的办法。 我们知道其实程序运行时就是使

weixin_45949006的博客 367

C语言之栈和队列的简单应用

知道了栈和队列的初步概念后,就需要开始运用它们做题; 在做题之前,了解几个小细节; 【1】当队头等于队尾等于0时,队列为空;当栈顶为0时,栈内为空; 【2】做题时一定要仔细看题目的要求,在对应的地方进行操作,比如说:题目是让你在所有的运算结束后再输出,那你的输出就一定要在最后。 【3】一般来说,题目都会有要求多组输入分别输出对应结果的,这个时候一定要注意:某些变量在新的一次运算开始之前需要重新赋值为0(这里只是我所遇到的一些情况); 【4】数组一定要开大,至少要比题目给出的需求大 题目1: 实

m0_62889505的博客 1086

栈和队列的实现及简单应用

一.栈 1)栈的实现 //用链表实现栈(链式储存结构) public class LLNode { public static void main(String[] args) { LLStack llStack = new LLStack(); llStack.push(1); llStack.push(2); llStack.push(3); System.out.println("栈里面的个数...

qq_61551764的博客 268

纸牌游戏---栈和队列简单应用

栈和队列的简单应用---扑克游戏,游戏规则很简单,首先将一副扑克牌均分成两份给两个玩家(甲乙),让甲先出牌,然后让乙出牌,并把牌放在甲的打出的牌上方,两人交替出牌。出牌时,如果某个玩家打出的牌和桌上某张牌一样,就可以将这两张一样的牌及两张牌中间所夹得牌全部收走,并依次放在自己手中的牌的末尾。如果有一个玩家手中没有牌了,游戏结束,对方赢得游戏。 假设只有12张牌,甲乙各6张牌,牌面只有数字1到9,...

咪*的博客 949

多项式的简单运算(栈和队列的应用)

思路: 首先要考虑存储多项式,只需存它每一项的系数和指数,用队列来存储比较方便,所以需要调用之前的链表队 列,将每一项的指数和系数当做一个数据存入队列。然后简单的加减乘除运算可以套用计算器(栈的应用), 只需将Stack_entry类型换为多项式即可。 **要求:**运算的多项式必须按未知数指数从大到小排列。 **多项式加法:**对比两个多项式的指数,指数相同的系数相加。 **...

qq_45234177的博客 1063

hdu1702--栈和队列的简单应用

#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<queue> #include<stack> #include<cstring> using namespace std; int main() { stack<int> st; queue<int> q; int t; sca

fusu123456789的博客 279

c++的STL中栈和队列的简单应用

1.栈和队列所在头文件 队列所在C++头文件 栈所在C++头文件 2.定义实现 queue q; stack s; 3.队列中的常见函数 q.empty();  bool型,判断队列是否为空 q.push(x);  将元素压如队尾 q.front();    返回队头元素,不删除 q.back();    返回队尾元素,不删除 q.pop();     删除队尾元素,不返值

qq_38946392的博客 496

简单数据结构(四)栈和队列的简单应用

编程判断一个字符串是否是回文。回文是指一个字符序列以中间字符为基准两边字符完全相同,如字符序列“ ACBDEDBCA”是回文。 算法思想:判断一个字符序列是否是回文,就是把第一个字符与最后一个字符相比较,第二个字符与倒数第二个字符比较,依次类推,第 i 个字符与第 n-i个字符比较。如果每次比较都相等,则为回文,如果某次比较不相等,就不是回文。因此,可以把字符序列分...

a361445613的博客 232

hdu 1702 栈和队列的简单应用

#include #include #include #include using namespace std; int main() {    int n,m,i,j,k,t;    char s[30];    scanf("%d",&t);    while(t--) {     scanf("%d%s",&n,s);     if(strcmp(s,"FIFO")==

晴朗的博客 577
上一篇: 异常及异常处理
Boolean120
博客等级 码龄6年 2粉丝 15原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值