#数据结构(二)--栈和队列
栈和队列
一栈
1.栈的顺序存储结构
特点:先进后出
栈是一种只能在一端进行插入或删除操作的线性表。
表中允许插入删除操作的一端为栈顶(top),表的另一端为栈底(bottom),

1 结构体的定义
#include <stdio.h>
typedef int ElemType;
#define MAX_SIZE 100typedef struct {int data[MAX_SIZE]; // 用于存储栈中的元素int top; // 栈顶指针,指向栈顶元素的索引
} SqStack;
2 初始化栈
栈顶指针赋值为-1
void InitStack(SqStack *&s) {s = (SqStack *) malloc(sizeof(SqStack));//申请一个顺序栈空间s->top = -1;//栈顶指针赋值为-1
}
3 销毁栈
释放节点空间
void DestroyStack(SqStack *&s) {free(s);
}
4 判断栈是否为空
指针为-1
bool StackEmpty(SqStack *&s) {return (s->top == -1);
}
5 进栈
先判断栈是否为满
注意先将指针++,再对栈顶元素进行赋值
bool PushStack(SqStack *&s, ElemType e) {if (s->top == MAX_SIZE - 1) {//栈满的情况return false;}s->top++;s->data[s->top] = e;//先加再赋值(s-data[++s->top])return true;
}
6 出栈
先对栈元素赋值,再将栈顶指针--
bool Pop(SqStack *&s, ElemType &e) {if (s->top == -1) {//栈空的情况return false;}e=s->data[s->top];s->top--;return true;
}
7 获取栈顶元素
bool GetTop(SqStack *s,ElemType &e){if (s->top==-1)return false;e=s->data[s->top];return true;
}
补充:共享栈
- 顺序栈采用一个数组存放栈中的元素。如果需要用到两个类型相同的栈,这时若为它们各自开辟一个数组空间,极有可能出现这样的情况:第一个栈已经满了,再进栈就溢出了,而另一个栈还有许多的空间。
- 共享栈是为了更有效地利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才会发生上溢。其存储数据的时间复杂度均为O(1),所以对存取效率没有什么影响。
- 栈空条件:栈0空为top==-1;栈1空为top1==MaxSize.
- 栈满条件:top==top1-1
- 元素进栈操作:进栈0操作为top0++;data[top0]=x;进栈1操作为top1--;data[top1]=x
- 元素出栈操作:出栈0操作为x=data[top0];top0--;出栈1操作为x=data[top1];top1++
- 在上述操作中,data数组表示共享栈的存储空间,top0和top1分别为两个栈的栈顶指针,这样该共享栈通过data,top0和top1来标识,也可以将他们设计为一个结构体类型。

2.栈的链式存储结构

栈中的数据元素的逻辑关系呈线性关系,所以栈可以像线性表一样采用链式存储结构
链栈通过单链表实现
不存在栈满上溢的情况,可以一直添加。
typedef struct linknode
{//定义链表节点数据ElemType data;//定义指针域,单链表的后继指针域struct linknode *next;
}LiStack;
栈的四要素:
-
栈空的条件:
s->next==NULL
bool StackEmpty(LiStack *s)
{return(s->next == NULL);
}
-
栈满的条件:
链栈不存在满的情况
-
进栈的条件
将带新元素的节点插入
//定义链表节点指针
LiStack *p;
//为新节点申请空间
p = (LiStack *)malloc(sizeof(LiStack));
//为新节点的数据区赋值
p -> data = e;
//头插法
//将新节点后继指针指向下一个节点 ,下一个节点插入前存放在头结点的后继指针
p -> next = s ->next;
//然后将头结点的后继指针指向新节点
s->next = p;
-
出栈的条件:
将栈顶节点删除
//传入要出栈的链栈 , 传入要出栈的指针元素
bool Pop(LiStack *&s , ElemType &e)
{//用指针指向要出栈的元素,就是头结点的后继节点LiStack *p;//如果s->next 为空,则表明为空栈 ,无法出栈元素if(s->next == NULL){return false;}//如果经过上面条件的验证,s->next不为空,则接着往下走//先定位要出栈的元素p = s->next; //头结点的后继节点e = p->data; //栈顶数据传出//开始删除头结点的后继节点 p,也就是头结点指向要删除节点的下一个节点s->next = p->next;//然后释放 p 空间free(p);return true;
}
二 队列
特点:先进先出
队列只允许在一端进行插入另一端进行删除,允许插入的时队尾,允许删除的时队头
插入元素称为入队,删除元素称为出队。

1 顺序队列
- 用一组地址连续的存储单元,以此存放从队头到队尾的数据元素,称为顺序队列。
- 需要附设两个指针,一个队头指针(front)一个队尾指针(rear),分别指向队头队尾。

- 初始时front和rear均为-1
- 元素进队rear加1
- front指向队首元素的前一位置
- 队满条件:rear==MaxSize-1
- 队空条件:front==rear
- 进队操作:元素进队rear++,data[rear]=e
- 出队操作:元素出队front++,e=data[front]
顺序队中实现队列的基本运算算法
结构体声明
typedef struct {ElemType data[MaxSize];//存放队中元素int front,rear;//队头和队尾指针
}SqQueue;
1 初始化
构造一个空队列q,将front和rear指针均设置为初始状态-1
void InitQueue(SqQueue *&q){q=(sqQueue *)malloc(sizeof(SqQueue));q->front=q->rear=-1;
}
2 入队
在队不满的情况下,先将队尾指针rear++,再将元素添加到该位置
bool enQueue(SqQueue *&q, ElemType e) {if (q->rear == MaxSize - 1)return false;q->rear++;q->data[q->rear] = e;return true;
}
3 出队
在队不空的情况下,将队首元素front++,再将该位置的元素赋值给e
bool deQueue(SqQueue *&q, ElemType &e) {if (q->front == q->rear)return false;q->front++;e = q->data[q->front];return true;
}
2 环形队列:

这是因为采用了rear=MaxSize-1作为队满条件的缘故,当出现这种情况可能会出现还有空间没有填满的情况。这种情况称为假溢出。
解决方案:环形队列

实际上地址一定是连续的不可能是环形的,这里是通过逻辑方式实现环形队列
- rear=(rear+1)%MaxSize
- front=(front+1)%MaxSize

- 队空条件:rear==front
- 队满条件:(rear+1)%MaxSize==front
- 进队操作:rear=(rear+1)%MaxSize,并且将e放在rear处
- 出队操作:front=(front+1)%MaxSize,将front位置e取出
- 这种情况下会比原先少放一个元素
相关计算:

3 链队
- 采用链表存储的称为链队。

相关操作:

单链表中数据节点类型DataNode声明如下
typedef struct qnode{ElemType data;struct qnode *next;
}DataNode;
链队节点类型LinkQuNode声明如下
typedef struct {DataNode *front;DataNode *rear;
}LinkQuNode;
链队四要素:
- 链队为空的判断条件:front=rear=NULL
- 链队为满的判断条件:不考虑
- 链队插入的判断条件:将含e的单链表节点插入至链表结尾
- 链队删除的判断条件:将单链表的首元节点删除
代码实现;
#include <stdio.h>
#include <cstdlib>typedef int ElemType;
typedef struct qnode {ElemType data;//存放元素struct qnode *next;//下一个节点指针
} DataNode;//数据节点的类型typedef struct {DataNode *front;DataNode *rear;
} LinkQuNode;
初始化:
void InitQueue(LinkQuNode *&q) {q = (LinkQuNode *) malloc(sizeof(LinkQuNode));q->front = q->rear = NULL;
}
判断是否为空:
bool QueueEmpty(LinkQuNode *q) {return (q->rear == NULL);
}
进队列
bool enQueue(LinkQuNode *&q, ElemType e) {DataNode *p;p = (DataNode *) malloc(sizeof(DataNode));p->data = e;p->next = NULL;if (q->rear == NULL)q->front = q->rear = p;else {q->rear->next = p;q->rear = p;}return true;
}
出队列
bool deQueue(LinkQuNode *&q, ElemType &e) {DataNode *t;if (q->rear == NULL)return false;t = q->front;if (q->front == q->rear)q->front = q->rear = NULL;elseq->front = q->front->next;e = t->data;free(t);return true;
}
4 双端队列
所谓双端队列是指两端都可以进行进队和出队的操作的队列,将队列的两端分别成为前端和后端,两端都可以进队和出队。

相关文章:
#数据结构(二)--栈和队列
栈和队列 一栈 1.栈的顺序存储结构 特点:先进后出 栈是一种只能在一端进行插入或删除操作的线性表。 表中允许插入删除操作的一端为栈顶(top),表的另一端为栈底(bottom), 1 结构体的定义 …...
react18中的函数组件底层渲染原理分析
react 中的函数组件底层渲染原理 react组件没有局部与全局之分,它是一个整体。这点跟vue的组件化是不同的。要实现 react 中的全局组件,可以将组件挂在react上,这样只要引入了react,就可以直接使用该组件。 函数式组件的创建 …...
提升产品竞争力之--IPD产品成本篇
在汉捷的咨询过程中,很多企业老总交流时都会提起这个抱怨:“现在产品竞争太激烈了,客户买产品首先看价格,你价格高一点就买别家的啦……” 汉捷咨询在前文谈到“通过定义产品包需求,来提升产品竞争力。差异化开发&…...
如何在Debian操作系统上安装Docker
本章教程,主要介绍如何在Debian 11 系统上安装Docker。主要使用一键安装Docker脚本和一键卸载脚本来完成。 一、安装Docker #!/bin/bashRED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m BLUE\033[0;34m NC\033[0mCURRENT_DIR$(cd "$(dirname "$0")…...
ArrayList和Array、LinkedList、Vector 间的区别
一、ArrayList 和 Array 的区别 ArrayList 内部基于动态数组实现,比 Array(静态数组) 使用起来更加灵活: ArrayList 会根据实际存储的元素动态地扩容或缩容,而 Array 被创建之后就不能改变它的长度了。ArrayList 允许…...
Linux开发环境配置(下)
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿…...
系统开发常用命令合集
本文还会持续更新,大家可以点赞收藏~ ifconfig ifconfigwlan0表示无线网络接口 eth0表示以太网接口(有线) HWaddr是接口的物理地址(MAC地址) inet addr是接口的IPv4地址 Bcast是广播地址,Mask是子网掩码 …...
Termius工具在MAC的使用出现的问题:
Termius工具在MAC的使用出现的问题: 在使用SFTP时,出现不了本地的文件的位置 解决方案: 在Apple store下载的使用不了LOCAL SFTP, 需要在网页上进行下载才可以: 官网下载地址:https://termius.com/down…...
浅析Android中View的绘制流程
前言 在《浅析Android中View的测量布局流程》中分析了VSYNC信号到达App进程之后开启的View布局过程,经过对整个View树进行遍历进行测量和布局,最终确定View的大小以及在屏幕中所处的位置。但是如果用户想在屏幕上看到View的内容还需要经过绘制来生成图形…...
pikachu靶场- 文件上传unsafe upfileupload
pikachu靶场- unsafe upfileupload 概述client checkMIME typegetimagesize() 概述 不安全的文件上传漏洞概述 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断…...
java中this的内存原理是?
在Java中,this关键字是一个特殊的引用,指向当前对象的实例。它在以下几个方面发挥重要作用: 指向当前对象:this可以用来访问当前对象的属性和方法,尤其在参数命名与实例变量重名时,用于区分。 构造函数&a…...
Matlab 车牌识别技术
1.1设计内容及要求: 课题研究的主要内容是对数码相机拍摄的车牌,进行基于数字图像处理技术的车牌定位技术和车牌字符分割技术的研究与开发,涉及到图像预处理、车牌定位、倾斜校正、字符分割等方面的知识,总流程图如图1-1所示。 图1-1系统总…...
CUDA-求最大值最小值atomicMaxatomicMin
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 实现原理 atomicMax和 atomicMin是 CUDA 中的原子操作,用于在并行计算中安全地更新共享变量的最大值和最小值。它们确…...
新的Midjourney就是一个增强版的Photoshop,你现在可以轻松的用它换衣服、换发型了
好久没有聊 Midjourney 了,昨晚他们发布了一项引人注目的新功能:AI 图像编辑,一个基于网页的加强版的 Photoshop 呼之欲出,让我大为震撼,也让用户们赞叹不已。 基于现有图像进行参考,进而生成新的图片&…...
Linux系统安装软件的4种方式【源码配置编译安装、yum安装、rpm包安装、二进制软件包安装(.rpm/.tar.gz/.tgz/.bz2)】
一.源码安装 linux安装软件采用源码安装灵活自由,适用于不同的平台,维护也十分方便。 (一)源码安装流程 源码的安装一般由3个步骤组成: 1.配置(configure) Configure是一个可执行脚本…...
基于Spring Boot的洪涝灾害应急信息管理系统设计与实现
摘要 近年来,全球气候变化加剧,洪涝灾害频发,给各国的经济发展和人民生活带来了巨大的威胁。为了提高洪涝灾害的应急响应能力,开发高效的应急信息管理系统变得至关重要。本文基于Spring Boot框架,设计并实现了一个洪涝…...
912.排序数组(桶排序)
目录 题目解法 题目 给你一个整数数组 nums,请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。 解法 class Solution { public:vector<int> sortArray(vect…...
IPC 进程间通信 消息队列
操作系统内核中采用一个链式队列管理消息,每个节点就对应一个消息: 操作系统规定了单个消息的数据长度不能超过8k(8192个字节),一个消息队列的表长(节点数)最多不超过256个 利用消息队列进行通信的特点: 1. 全双工:任何参与通信的…...
opencv 图像翻转- python 实现
在做图像数据增强时会经常用到图像翻转操作 flip。 具体代码实现如下: #-*-coding:utf-8-*- # date:2021-03 # Author: DataBall - XIAN # Function: 图像翻转import cv2 # 导入OpenCV库path test.jpgimg cv2.imread(path)# 读取图片 cv2.namedWindow(image,1) …...
使用DolphinScheduler接口实现批量导入工作流并上线
使用DS接口实现批量导入工作量并上线脚本 前面实现了批量生成DS的任务,当导入时发现只能逐个导入,因此通过接口实现会更方便。 DS接口文档 DS是有接口文档的地址是 http://IP:12345/dolphinscheduler/swagger-ui/index.html?languagezh_CN&lang…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
