第三章 栈和队列【数据结构与算法】1

简介: 第三章 栈和队列【数据结构与算法】1

配套资源下载

数据结构资源下载导航【数据结构】

第 3 章 栈和队列

第2章介绍了线性表的概念,从数据结构上看,栈和队列也是线性表,只不过是两种特殊的 线性表。栈只允许在表的一端进行插入或删除操作,而队列只允许在表的一端进行插入操作、在另一端进行删除操作。因而,栈和队列也可以被称为操作受限的线性表。从数据类型的角度来看,栈与队列是与线性表不同的抽象数据结构。

3.1 应用实例

应用实例一 迷宫求解问题

这是实验心理学中的一个经典问题,心理学家用一个无顶盖的大盒子做成“迷宫”从然后把一只老鼠从入口处赶进迷宫。迷宫中设置了很多隔断,对老鼠的前进方向构成多处障碍,在迷宫的唯一出口处放置了一块奶酪,吸引老鼠寻找正确的通路以到达出口。


可以用一个mxn的方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计

一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得到没有通路的结论。


计算机解迷宫时,通常是采用“穷举求解”的方法,即从入口出发,沿某方向向前探索,若能 走通则继续往前走;否则沿原路返回,换一个方向再继续探索,直至所有可能的通路都探索到为止。为了保证在任何位置上都能沿原路退回,显然要用具有后进先出特性的栈来保存从入口到当前位置的路径。

应用实例二“马”踏棋盘问题

将棋子“马”随机地放在国际象棋8x8棋盘Board[8][8]的某个方格中,“马”按走棋规则进 行移动,要求每个方格只进入一次,走遍棋盘上所有的64个方格。编写(非)递归程序,求出“马” 的行走路线,并按求出的行走路线将数字1,2,…,64依次填入一个8x8的方阵并输出。


求解时可采用栈的数据结构,即将“马”的行走顺序压人栈中。每次在多个可走的位置中选 择其中一个进行试探,其余未曾试探过的可走位置必须用适当的结构妥善管理,以备试探失败时 的“回溯”(悔棋)使用。

以上实例的分析与实现将在3.4节详细介绍。

3.2栈

3.2.1 栈的概念及运算

栈(stack)是一种只允许在一端进行插人和删除操作的线性表,它是一
种操作受限的线性表

在表中允许进行插入和删除的一端称为“栈顶”(top),另一端称为“栈底”(bottom)。

栈的插入操作通常称为“入栈”或“进栈”(push),

而栈的删除操作则称为“出栈”或“退栈”(pop)。

当栈中无数据元素时,称为“空栈”。

栈具有后进先出的特性,因此又称为“后进先出”(Last In First Out,LIFO)表

栈的示意图



栈的基本运算有以下几种。
① InitStack(S) 初始化:初始化一个新的栈。
② Empy(S )栈的非空判断:若栈S不空,则返回TRUE;否则,返回FALSE。
③ Push(S.x) 入楼:在栈S的顶部插入元素x,若栈满,则返回FALSE;否则,返回TRUE
④ Pop(S) 出栈:若栈S不空,则返回栈顶元素,并从栈顶中删除该元素;否则,返回空元素  
⑤ GetTop(S) 取栈顶元素:若栈S不空,则返回栈顶元素;否则返回空元素NULL。
⑥ SetEmpty(S) 置栈空操作:置栈S为空栈。

栈是一种特殊的线性表,因此栈可采用顺序存储结构存储,也可以使用链式存储结构存储。

3.2.2栈的顺序存储结构

1. 顺序栈

利用顺序存储的方式实现的栈称为“顺序栈”。类似于顺序表的定义,栈中的数据元素用一个
预设的足够长度的一维数组来实现:ElemType elem[MAXSIZE]。栈底位置可以设置在数组任
一个端点,而栈顶是随着插人和删除而变化的。用int top来作为栈顶的指针,指明当前栈顶的    位置,同时将elem和top封装在一个结构中。顺序栈的类型描述如下。  
#define MAXSIZE<栈最大元素数>
typedef struct{ 
  ElemType elem[MAXSIZE];
  int top;
}SeqStack;

定义一个指向顺序栈的指针:

SeqStack *s;

常将0下标端设为栈底,这样空栈时校顶指针s->top=-1;入栈时,栈顶指针加1,即s->top++;出栈时,栈顶指针减1,即s->top–。

栈的基本操作如下

相关代码请看配套资源

1-顺序栈.c

#include<stdio.h> 
#include<stdlib.h> 
int main(){
  SeqStack *s=InitStack();
  printf("%d",Empty(s));//1 
  int x1=1;
  Push(s,x1);
  int x2=2;
  Push(s,x2);
  printf("%d",Empty(s));//0
  int x3;
  Pop(s,&x3);
  printf("%d",x3);//2
  int t=GetTop(s);
  printf("%d",t);//1
}

运行结果如下



2. 多栈共享邻接空间

栈的共享中最常见的是两栈共享
假设两个栈共享一维数组elem[MAXSIZE],则可以利用栈的“栈底位置不变,栈顶位置动态变化”特性,两个栈底分别为-1和MAXSIZE,而它们的栈顶都往中间方向延伸。因此,只要整个数组elem[MAXSIZE]未被满,无论哪个栈的人栈都不会发生上溢。


两栈共享的数据结构可定义如下。

typedef struct{
  ElemType elem[ MAXSIZE];
  int lefttop;//左栈栈顶位置指示器
  int righttop;//右栈栈顶位置指示器
} Dupsqstack;

两个栈共享邻接空间的示意图如图3-4所示。左栈入栈时,栈顶指针加1,右栈人栈时,栈顶指针减1。由于两个栈顶均可向中间伸展,互补余缺,因此使得每个栈的最大空间均大于MAXSIZE/2。


为了识别左右栈,必须另外设定标志:

char status;
status ='L';  //左栈
status ='R';//右栈

在进行栈操作时,需指定栈号status=L’为左栈,status='R’为右栈;判断栈满的条件如下:

s->lefttop+1=s->righttop;
目录
打赏
0
0
0
0
25
分享
相关文章
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
|
3月前
|
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
238 77
|
2月前
|
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
37 11
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
内网监控管理软件:PHP 语言队列算法揭秘
在数字化办公环境中,内网监控管理软件对企业的稳定运行和信息安全至关重要。本文深入介绍PHP中的队列算法及其在内网监控软件中的应用,包括监控数据收集、任务调度和日志记录等场景,通过代码示例展示其实现方法。队列算法可提高性能、保证数据顺序并实现异步处理,为企业提供高效的安全保障。
35 1
|
3月前
|
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
142 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
3月前
|
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
80 9
|
3月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
119 7
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
186 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
170 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等