数据结构-栈和队列
栈和队列
栈和队列都是线性数据结构,逻辑结构和线性表相同。
栈和队列的插入和删除操作受到某些限制,与线性表不同,也被称为操作受限的线性表。
栈
栈是一种插入和删除都只能在表的同一端操作的线性表。
允许进行插入和删除操作的一端叫栈顶(Top),也叫表尾;另一端叫做栈底(Bottom),也叫表头。
栈中没有元素时称为空栈。
向栈中插入元素的操作称为进栈或入栈(push),从栈中删除元素的操作称为退栈或出栈(pop)。
栈是按照先进后出(FILO,First In Last Out)或后进先出(LIFO,Last In First Out)的原则组织数据。
栈的基本操作
创建一个空栈;删除一个栈;判断栈是否为空;判断栈是否为满;栈顶插入一个元素;求栈顶元素的值;删除栈顶的一个元素;输出栈。
栈的抽象数据类型
顺序栈
采用顺序存储结构表示的栈称为顺序栈。
顺序栈需要分配一块连续的存储区域来存放栈中的元素。
顺序栈可以用一维数组实现。
栈底位置固定不变,可以吧栈底设置在一维数组任意一端。
栈顶位置随着进栈和出栈操作不断变化,因此用一个变量来指示当前栈顶位置。
顺序栈类模板:栈中最大元素个数为MaxSize,顺序类模板名称LinearStack
将栈顶top赋值为-1,表示空栈。
当栈中已有MaxSize个元素,如果再进行进栈操作,就会产生溢出,称为上溢;对空栈进行出栈操作时也会产生溢出,称为下溢。
进行进栈出栈操作时,应先检查栈是否为满(IsFull)或是否为空(IsEmpty);
IsEmpty()的算法是:return top==-1;
IsFull()的算法是:return top+1=MaxSize;
求栈中元素的个数GetElementNumber()的算法:return top+1;
进栈操作Push(const T& x)的算法:
Pop(T& x)出栈操作算法:
顺序栈的基本操作实现
顺序栈的应用
链式栈
把栈组织成一个单向链表,即采用链接结构来表示栈,这样的数据结构称为链接栈。
每一个结点表示栈中的一个元素。
栈是在链表头部进行插入和删除操作,故链接栈不需要再设置表头结点。
链接栈具有动态分配元素结点的特点,内存足够的情况下,链接栈中最大元素的个数没有限制。没有判断栈满的方法,IsFull
其他操作和顺序栈基本操作含义相同。
链接栈存储结点类模板
进栈操作Push:向链接栈的栈顶插入一个元素结点,先将待进栈的结点的指针域指向原来的栈顶结点,然后将栈顶指针top指向该结点。
出栈操作Pop:从链表的栈顶删除一个元素结点,先将栈顶元素取出放到x中,然后使栈顶指针top指向原栈顶结点的后继结点,然后物理上删除该结点。当top为空时,链接栈为空。
链接栈基本操作实现
队列
队列是一种只允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表。
队列的插入操作称为入队,允许入队的一端称为队尾(rear)。
队列的删除操作称为出队,允许出队的一端称为队头(front)。
不含元素的队列称为空队列。
队列是先进先出(FIFO,First In First Out)或后进后出(LILO,Last In Last Out)的线性表。
队列的基本操作
队列的抽象数据类型
顺序队列
采用顺序存储结构的队列称为顺序队列。
顺序队列用一个一维数组来存放队列中的数据元素,此外设置两个整型变量front和rear,分别指示队头和队尾,称为头指针和尾指针。
约定:为了运算方便,约定在非空队列里,front始终指向队头元素,rear始终指向队尾元素的下一个位置;初始化队列时,front和rear均置为0;在队列中,由front和rear共同反应队列中元素动态变化的情况。
入队操作:将新元素插入到rear所指位置,再将rear的值加1。
出队操作:删除front所指位置的元素后,再将front的值加1并返回被删元素。
队列为空的条件:front==rear
队列存在溢出问题:当队列满时,再做入队操作,称为上溢;当队列空时,再做出队操作,称为下溢。
假上溢:front和rear随着队列插入和删除操作变化,某种状态下,队列的实际可用空间没有占满,但尾指针已超越存储空间的上界,也不能做入队操作,此时称为假上溢。
循环队列
为避免假上溢出现,充分利用队列的存储空间,将顺序队列存储空间的最后一个位置和第一个位置逻辑上连接在一起,这样的队列称为循环队列。
实现:
假设当前队列最多容纳MaxSize个元素,逻辑上的循环通过头、尾指针加1操作实现,当头、尾指针指向存储空间的上界,通过下面逻辑将头、尾指针指向下界0:
front =(front+1)%(MaxSize); rear = (rear+1)%(MaxSize);
循环队列示意图
循环队列无法依据头尾指针相等判断队列是空是满。
判断循环队列是空是满的两种办法:
1、约定少用一个元素空间。入队前,如果关系(rear+1)%(MaxSize)==front 存在,就认为队列已满。这个方法rear始终指向那个空闲的元素空间。
2、使用一个计数器size记录当前队列的实际长度。如果size=0,当front==rear时,当前队列是空队列,可以进行入队操作;否则,当前队列满,不能入队。
顺序循环队列类模板
顺序循环队列的基本实现
顺序循环队列的应用
链接队列
采用链式存储结构的队列称为链接队列。
队列的链式存储结构是仅在表头删除结点和在表尾插入结点的单链表。
链接队列中,需要增加指向队头和队尾的两个指针front和rear。
链接队列由一个头指针front和一个尾指针rear唯一确定。
链接队列存储结点类模板
链接队列类模板
链接队列基本操作实现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具