#数据结构(二)--栈和队列
栈和队列
一栈
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…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
