第3章 栈和队列07
数据结构-Java语言描述 第三章 栈和队列
System.exit(1);
}
栈顶指针top的初始值决
top=-1;
定了后续其他方法的实现
stackArray=(T[])new Object[n];
}
【算法3-2】入栈
public void push(T obj)
{
if(top==stackArray.length-1){
T []p=(T[])new Object [top*2];
(b)元素a2入栈
an … … a2 a1
(c)元素an入栈
an-1 … a2 a1
(d)元素an出栈
a2 a1
(e)元素a3出栈
a1
(f)元素a2出栈
【例3-1】一个栈的输入序列是1、2、3、4、5,若在 入栈的过程中允许出栈,则栈的输出序列4、3、5、1、 2可能实现吗?1、2、3、4、5的输出呢?
型 正序遍历:依次访问栈中每个元素并输出
3.1.2 顺序栈
顺序栈泛型类的定义如下:
public class sequenceStack<T> {
顺序栈中一维数组 的初始长度
final int MaxSize=10;
private T[] stackArray; 存储元素的数组对象
private int top;
public void nextOrder() {
for(int i=top;i>=0;i--) System.out.println(stackArray[i]);
}
【算法3-8】清空栈操作
public void clear() {
top=-1; }
3.1.3 链栈
栈的链接存储结构称为链栈。结点类的定义,同 第二章Node类。
数据结构(C语言)第3章 栈和队列
Data Structure
2013-8-6
Page 13
栈的顺序存储(顺序栈)
利用一组地址连续的存储单元依次存放自栈底到栈顶的数 据元素。 结构定义: #define STACK_INIT_SIZE 100; // 存储空间初始分配量 #define STACKINCREMENT 10; // 存储空间分配增量 typedef struct { SElemType *base; // 存储空间基址 SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素位单位 } SqStack;
解决方案2:
顺序栈单向延伸——使用一个数组来存储两个栈
Data Structure 2013-8-6 Page 21
两栈共享空间 两栈共享空间:使用一个数组来存储两个栈,让一个 栈的栈底为该数组的始端,另一个栈的栈底为该数组 的末端,两个栈从各自的端点向中间延伸。
Data Structure
2013-8-6
链栈需要加头结点吗? 链栈不需要附设头结点。
Data Structure
2013-8-6
Page 27
栈的链接存储结构及实现
Data Structure
2013-8-6
Page 11
GetTop(S, &e) 初始条件:栈 S 已存在且非空。 操作结果:用 e 返回S的栈顶元素。 Push(&S, e) 初始条件:栈 S 已存在。 操作结果:插入元素 e 为新的栈顶元素。 Pop(&S, &e) 初始条件:栈 S 已存在且非空。 操作结果:删除 S 的栈顶元素,并用 e 返回其值。
Data Structure
大学数据结构课件--第3章 栈和队列
栈满 top-base=stacksize
top
F
E
D C B
top top top top top top base
入栈PUSH(s,x):s[top++]=x; top 出栈 POP(s,x):x=s[--top]; top
base
4
A
3.1 栈
例1:一个栈的输入序列为1,2,3,若在入栈的过程中 允许出栈,则可能得到的出栈序列是什么? 答: 可以通过穷举所有可能性来求解:
3.2 栈的应用举例
二、表达式求值
“算符优先法”
一个表达式由操作数、运算符和界限符组成。 # 例如:3*(7-2*3) (1)要正确求值,首先了解算术四则运算的规则 a.从左算到右 b.先乘除后加减 c.先括号内,后括号外 所以,3*(7-2*3)=3*(7-6)=3*1=3
9
3.2 栈的应用举例
InitStack(S); while (!QueueEmpty(Q))
{DeQueue(Q,d);push(S,d);}
while (!StackEmpty(S)) {pop(S,d);EnQueue(Q,d);} }
第3章 栈和队列
教学要求:
1、掌握栈和队列的定义、特性,并能正确应用它们解决实 际问题;
用一组地址连续的存储单元依次存放从队头到队尾的元素, 设指针front和rear分别指示队头元素和队尾元素的位置。
Q.rear 5 4 Q.rear 3 2 3 2 5 4 Q.rear 3 3 5 4 5 4
F E D C
C B A
Q.front
2 1 0
C B
Q.front 2 1 0
第3章栈和队列-数据结构与算法(第2版)-汪沁-清华大学出版社
an
队头
队尾
队列示意图
入队
13
2、队列的基本运算
初始化队列 INIQUEUE(&Q)
将队列Q设置成一个空队列。
入队列
ENQUEUE(&Q,X)
将元素X插入到队尾中,也称“进队” ,“插入”。
出队列
DLQUEUE(&Q)
将队列Q的队头元素删除,也称“退队”、“删除”。
取队头元素 GETHEAD(Q)
也就是说,栈是一种后进先出(Last In First Out)的线性表,简称为LIFO表。
3
2、栈的运算
初始化栈:INISTACK(&S)
将栈S置为一个空栈(不含任何元素)。
进栈:PUSH(&S,X)
将元素X插入到栈S中,也称为 “入栈”、 “插入”、 “压 入”。
出栈: POP(&S)
删除栈S中的栈顶元素,也称为”退栈”、 “删除”、 “弹 出”。
9
三、链栈
typedef struct Lsnode { ElemType data;
struct Lsnode *next; } Lsnode *top;
一个链表栈由ቤተ መጻሕፍቲ ባይዱ顶指针top唯一确定。
10
1、链栈的主要运算
进栈操作 void Push(Lsnode *top; ElemType x)
{ p=(Lsnode *)malloc(sizeof(Lsnode)); p->data=x; p->next=top->next; top->next=p; }/*Push*/
第3章 栈和队列
1
栈和队列是二种特殊的线性表。是操作受 限的线 性表。 一、栈
数据结构第三章 数据结构堆栈和队列
数据结构第三章数据结构堆栈和队列在计算机科学中,数据结构是组织和存储数据的方式,以便能够高效地访问和操作这些数据。
在数据结构的众多类型中,堆栈和队列是两种非常重要且常用的结构。
首先,让我们来了解一下堆栈。
堆栈就像是一个垂直堆放的容器,遵循着“后进先出”(Last In First Out,简称LIFO)的原则。
想象一下,你有一堆盘子,每次你把新盘子放在最上面,而当你要取盘子时,也只能从最上面拿。
这就是堆栈的工作方式。
在编程中,堆栈有着广泛的应用。
比如,函数调用就是一个典型的例子。
当一个函数调用另一个函数时,新函数的信息被压入堆栈。
当被调用的函数执行完毕后,其信息从堆栈中弹出,程序回到原来的函数继续执行。
此外,表达式求值也常常会用到堆栈。
例如,计算一个复杂的算术表达式时,可以将操作数和运算符依次压入堆栈,然后按照特定的规则进行计算。
堆栈的实现可以通过数组或者链表来完成。
如果使用数组实现,需要注意堆栈的大小可能会有限制。
而链表实现则相对灵活,但其操作的复杂度可能会略高一些。
接下来,我们再看看队列。
队列则像是一条排队的队伍,遵循“先进先出”(First In First Out,简称 FIFO)的原则。
就好比在银行排队办理业务,先来的人先得到服务并离开队伍。
在实际应用中,队列也非常有用。
例如,打印机的打印任务队列就是一个典型的例子。
新的打印任务被添加到队列的末尾,而打印机按照任务进入队列的顺序依次处理。
还有操作系统中的任务调度,也常常会用到队列来管理等待执行的任务。
队列同样可以通过数组或者链表来实现。
使用数组实现时,可能会面临队列前端元素删除后空间浪费的问题。
而链表实现虽然可以避免这个问题,但需要额外的指针操作。
那么,堆栈和队列在操作上有哪些不同呢?对于堆栈,主要的操作是入栈(push)和出栈(pop)。
入栈就是将元素添加到堆栈的顶部,出栈则是从堆栈的顶部取出元素。
而对于队列,主要的操作是入队(enqueue)和出队(dequeue)。
《栈和队列》课件
栈与队列的区别
数据存储方式
栈是后进先出(Last In First Out, LIFO)的数据结构,新元素总是被添加到栈顶,移除 元素时也是从栈顶开始。而队列是先进先出(First In First Out, FIFO)的数据结构,新 元素被添加到队列的尾部,移除元素时从队列的头部开始。
操作方式
栈的主要操作有push(添加元素)和pop(移除元素),而队列的主要操作有enqueue (添加元素)和dequeue(移除元素)。
《栈和队列》ppt课件
目录
CONTENTS
• 栈的定义与特性 • 队列的定义与特性 • 栈与队列的区别与联系 • 栈和队列的实现方式 • 栈和队列的算法实现 • 总结与思考
01 栈的定义与特性
CHAPTER
栈的定义
栈是一种特殊的线性 数据结构,遵循后进 先出(LIFO)原则。
栈中的元素按照后进 先出的顺序排列,最 新加入的元素总是位 于栈顶。
02
如何实现一个队列,并 实现其基本操作( enqueue、dequeue、 front)?
03
栈和队列在应用上有哪 些区别?请举例说明。
04
请设计一个算法,使用 栈实现括号匹配的功能 ,并给出测试用例。
谢谢
THANKS
。
队列的应用场景
任务调度
在任务调度中,可以将任 务按照优先级放入队列中 ,按照先进先出的原则进 行调度。
网络通信
在网络通信中,可以将数 据包放入队列中,按照先 进先出的原则进行发送和 接收。
事件处理
在事件处理中,可以将事 件放入队列中,按照先进 先出的原则进行处理。
03 栈与队列的区别与联系
CHAPTER
应用场景
《数据结构课件、代码》第3章栈和队列
栈也可以通过链表实现,其中链表的 头部作为栈顶。
在Java中,可以使用`java.util.Stack` 类实现栈,该类继承自`Vector`类, 提供了丰富的操作方法来管理栈。
总结词
应用场景不同
详细描述
栈常用于实现函数调用、括号匹配等后进 先出的操作。而队列常用于实现任务调度 、缓冲区处理等先进先出的操作。
THANKS
感谢观看
04
栈和队列的算法复杂度分 析
算法时间复杂度分析
栈的常见操作包括push、pop和peek等,其中push和pop操 作的时间复杂度为O(1),而peek操作的时间复杂度也为O(1)。
队列的常见操作包括enqueue、dequeue和peek等,其中 enqueue操作的时间复杂度为O(1),dequeue操作的时间复杂 度为O(n),n为队列中元素的个数,peek操作的时间复杂度为 O(1)。
算法空间复杂度分析
栈的空间复杂度主要取决于其存储方 式,如果使用数组实现,则空间复杂 度为O(n),n为栈中元素的个数;如 果使用链表实现,则空间复杂度为 O(1)。
队列的空间复杂度也取决于其存储方式, 如果使用数组实现,则空间复杂度为 O(n),n为队列中元素的个数;如果使 用链表实现,则空间复杂度为O(1)。
《数据结构课件、代 码》第3章栈和队列
目录
• 栈(Stack) • 队列(Queue) • 栈与队列的应用 • 栈和队列的算法复杂度分析 • 数据结构中的栈和队列与其他数据结构的比较
01
栈(Stack)
栈的定义
01
数据结构课件第3篇章栈和队列
循环队列实现原理
01
循环队列定义
将一维数组看作首尾相接的环形结构,通过两个指针(队头和队尾指针)
在数组中循环移动来实现队列的操作。当队尾指针到达数组末端时,再
回到数组起始位置,形成循环。
02
判空与判满条件
在循环队列中,设置一个标志位来区分队列为空还是已满。当队头指针
等于队尾指针时,认为队列为空;当队尾指针加1等于队头指针时,认
栈在函数调用中应用
函数调用栈
在程序执行过程中,每当发生函数调用时,系统会将当前函数的执行上下文压入一个专门的栈中,称为函数调用 栈。该栈用于保存函数的局部变量、返回地址等信息。当函数执行完毕后,系统会从函数调用栈中弹出相应的执 行上下文,并恢复上一个函数的执行状态。
递归调用实现
递归调用是一种特殊的函数调用方式,它通过在函数调用栈中反复压入和弹出同一函数的执行上下文来实现对问 题的分解和求解。在递归调用过程中,系统会根据递归深度动态地分配和管理函数调用栈的空间资源。
栈和队列的应用
栈和队列在计算机科学中有着广泛的应用,如函数调用栈、表达式求 值、缓冲区管理等。
常见误区澄清说明
误区一
栈和队列的混淆。虽然栈和队列都是线性数据结构,但它们的操作方式和应用场景是不同的。栈是后进先出,而队列 是先进先出。
误区二
认为栈和队列只能通过数组实现。实际上,栈和队列可以通过多种数据结构实现,如链表、循环数组等。具体实现方 式取决于应用场景和需求。
后缀表达式求值
利用栈可以方便地实现后缀表达式的求值。具体步骤 为:从左到右扫描表达式,遇到数字则入栈,遇到运 算符则从栈中弹出所需的操作数进行计算,并将结果 入栈,最终栈中剩下的元素即为表达式的结果。
中缀表达式转换为后缀表达式
数据结构第三章 数据结构堆栈和队列
数据结构第三章数据结构堆栈和队列数据结构第三章数据结构堆栈和队列3.1 堆栈堆栈(Stack)是一种遵循后进先出(Last In First Out,LIFO)原则的线性数据结构。
堆栈中只有一个入口,即栈顶,所有的插入和删除操作都在栈顶进行。
3.1.1 堆栈的基本操作- Push:将元素插入到栈顶- Pop:从栈顶删除一个元素- Top:获取栈顶元素的值- IsEmpty:判断栈是否为空- IsFull:判断栈是否已满3.1.2 堆栈的实现堆栈可以使用数组或链表来实现。
- 基于数组的堆栈实现:使用一个数组和一个指针来表示堆栈,指针指向栈顶元素的位置。
Push操作时,将元素插入到指针指向的位置,然后将指针向上移动;Pop操作时,将指针指向的元素弹出,然后将指针向下移动。
- 基于链表的堆栈实现:使用一个链表来表示堆栈,链表的头结点表示栈顶元素。
Push操作时,创建一个新节点并将其插入链表的头部;Pop操作时,删除链表的头结点。
3.1.3 堆栈的应用堆栈广泛应用于各种场景,如函数调用栈、表达式求值、括号匹配等。
3.2 队列队列(Queue)是一种遵循先进先出(First In First Out,FIFO)原则的线性数据结构。
队列有两个端点,一个是入队的端点(队尾),一个是出队的端点(队首)。
3.2.1 队列的基本操作- Enqueue:将元素插入到队尾- Dequeue:从队首删除一个元素- Front:获取队首元素的值- Rear:获取队尾元素的值- IsEmpty:判断队列是否为空- IsFull:判断队列是否已满3.2.2 队列的实现队列可以使用数组或链表来实现。
- 基于数组的队列实现:使用一个数组和两个指针来表示队列,一个指针指向队首元素,一个指针指向队尾元素的下一个位置。
Enqueue操作时,将元素插入到队尾指针所指向的位置,然后将队尾指针向后移动;Dequeue操作时,将队首指针指向的元素弹出,然后将队首指针向后移动。
数据结构实用教程(C语言版) 第3章 栈和队列
3.1.1 栈的概念
假设有一个栈S=(a1,a2,…,an),栈 中元素按a1,a2,…,an的次序进栈后, 进栈的第一个元素a1为栈底元素,出栈的第 一个元素an为栈顶元素,也就是出栈的操作 是按后进先出的原则进行的,其结构如图31所示。
图3-1栈结构示意图
返回到本节目录
3.1.2栈的基本操作
3.1.3顺序栈
由于栈是操作受限制的线性表,因此与线性表类似,栈也 有两种存储结构,即顺序存储结构和链式存储结构。 1. 顺序栈的定义 栈的顺序存储结构称为顺序栈。类似于顺序表的类型定义,顺 序栈是用一个预设的足够长度的一维数组和一个记录栈顶元素 位置的变量来实现。顺序栈中栈顶指针与栈中数据元素的关1.3顺序栈
3. 顺序栈的基本操作实现
(3)进栈操作 进栈操作的过程如图3-3所示。先判断栈S如图3-3(a) 是否为满,若不满再将记录栈顶的下标变量top加1如 图3-3(b),最后将进栈元素放进栈顶位置上如图33(c)所示,算法描述见算法3.3。
图3-3 进栈操作过程图
返回到本节目录
栈除了在栈顶进行进栈与出栈外,还有初始化、判空 等操作,常用的基本操作有: (1)初始化栈InitStack(S)。其作用是构造一个空 栈 S。 (2)判断栈空EmptyStack(S)。其作用是判断是 否是空栈,若栈S为空,则返回1;否则返回0。 (3)进栈Push(S,x)。其作用是当栈不为满时,将 数据元素x插入栈S中,使其为栈S的栈顶元素。 (4)出栈Pop(S,x)。其作用是当栈S不为空时,将 栈顶元素赋给x,并从栈S中删除当前栈顶元素。 (5)取栈顶元素GetTop(S,x)。其作用是当栈S不 为空时,将栈顶元素赋给x并返回,操作结果只是 读取栈顶元素,栈S不发生变化。 返回到本节目录
数据结构与算法C版课件第三章栈和队列
不改变栈的状态。
4.栈的存储 (1)采用顺序方式存储的栈称为顺序栈(sequential stack) (2) 采用链接方式存储的栈称为链栈(linked stack)
3.1.2 顺序栈及运算的算法实现
用栈来实现括号匹配检查的原则是,对表达式从左到右扫描。 (1)当遇到左括号时,左括号入栈; (2)当遇到右括号时,首先检查栈是否空,若栈空,则表明该“右括弧”多余;否则比 较栈顶左括号是否与当前右括号匹配,若匹配,将栈顶左括号出栈,继续操作;否则,表明 不匹配,停止操作。 (3)当表达式全部扫描完毕,若栈为空,说明括号匹配,否则表明“左括弧”有多余的。
出队
a1 a2 a3 a4 a5
入队
队列图示
4.队列的应用
5. 在队列上进行的基本运算
(1)队列初始化initQueue(q):构造一个空队列。 (2)判队空emptyQueue(q):若q为空队则返回为1,否
则返回为0。
(3)入队enQueue(q,x):对已存在的队列q,插入一个元素x
到队尾,队发生变化。
队列中元素个数的计算公式。
(4)出队deQueue(q,x):删除队头元素,并通过x返回其值,
队发生变化。
(5)读队头元素frontQueue(q):读队头元素,并返回其值,
队不变。
3.2.2 顺序队列及运算的实现
采用顺序方法存储的队列称为顺序队列(sequential queue)
顺序队列的存储结构用c语言定义如下:
#define MAXSIZE 1024
运算受限的线性 表
表两端插删
第3章数据结构栈和队列
第3章数据结构栈和队列数据结构是计算机科学中重要的基础知识之一,它是用于组织和管理数据的方法。
栈和队列是其中两种常见的数据结构,它们分别以后进先出(Last In First Out,LIFO)和先进先出(First In First Out,FIFO)的方式操作数据。
本文将详细介绍栈和队列的概念、特点以及应用。
一、栈栈是一种限制仅在表尾进行插入和删除操作的线性表。
插入和删除操作称为入栈和出栈,即数据项的入栈相当于把数据项放入栈顶,而数据项的出栈相当于从栈顶移除数据项。
栈具有后进先出的特点,即后入栈的数据项先出栈,而最先入栈的数据项最后出栈。
类比现实生活中的例子就是一叠盘子,我们只能从最上面取盘子或放盘子。
栈的实现方式有两种:基于数组和基于链表。
基于数组的栈实现相对简单,通过一个数组和一个指向栈顶的指针来完成栈的操作。
基于链表的栈实现则需要定义一个节点结构,每个节点包含一个数据域和一个指向下一个节点的指针,通过头指针来操作栈。
栈的应用非常广泛,比如浏览器中的返回功能就是通过栈来实现的。
当我们点击浏览器的返回按钮时,当前页面会入栈,点击前进按钮时,当前页面会出栈。
在编程中,栈也被广泛应用,比如函数调用栈用于存储函数调用的上下文信息。
二、队列队列是一种限制仅在表头删除和在表尾插入的线性表。
表头删除操作称为出队列,表尾插入操作称为入队列。
和栈不同,队列采用先进先出的原则,即最先入队列的元素最先出队列。
队列的实现方式也有两种:基于数组和基于链表。
基于数组的队列实现和栈类似,通过一个数组和两个指针(一个指向队头,一个指向队尾)来完成队列的操作。
基于链表的队列实现则需要定义一个节点结构,每个节点包含一个数据域和一个指向下一个节点的指针,通过头指针和尾指针来操作队列。
队列同样具有广泛的应用,比如操作系统中的进程调度就是通过队列来实现的。
CPU会按照进程到达的顺序,依次从队列中取出进程进行执行。
在编程中,队列也常用于解决一些需要按顺序处理数据的问题。
数据结构第三章栈和队列
性能比较与选择依据
性能比较
栈和队列的时间复杂度均为O(1),空间复杂度均为O(n)。在实际应用中,栈通常用于 需要后进先出(LIFO)的场景,而队列则用于需要先进先出(FIFO)的场景。
选择依据
在选择使用栈还是队列时,应根据具体需求和应用场景进行判断。如果需要后进先出的 特性,应选择栈;如果需要先进先出的特性,则应选择队列。同时,还需要考虑数据结
栈中的元素只能在栈顶进行插入和删 除操作。
栈具有记忆功能,能保存数据元素进 入栈的先后顺序。
栈的基本操作
01
入栈(Push):在栈顶 插入一个元素。
02
出栈(Pop):删除栈 顶元素并返回其值。
03
查看栈顶元素(Top) :返回栈顶元素的值, 但不删除该元素。
04
判断栈是否为空( IsEmpty):检查栈中 是否还有元素。
回溯到上一个状态。
广度优先搜索中的队列应用
搜索队列
广度优先搜索使用队列来保存待 搜索的节点,按照先进先出的原
则进行搜索。
状态转移
在广度优先搜索中,队列用于保存 状态转移的信息,以便在搜索过程 中根据状态转移规则进行状态的扩 展和搜索。
最短路径问题
广度优先搜索可用于解决最短路径 问题,通过队列保存待访问的节点 ,并按照距离起始节点的远近进行 排序和访问。
其他算法中的栈和队列应用
深度优先搜索
在深度优先搜索中,栈用于保存当前路径的状态信息,以便在需要时 回溯到上一个状态。
括号匹配问题
栈可用于解决括号匹配问题,遇到左括号时将其压入栈中,遇到右括 号时从栈中弹出左括号并判断是否匹配。
表达式求值
栈可用于表达式求值中,保存操作数和运算符,并按照运算优先级进 行求值。
数据结构第三章 栈和队列
计 3467
433
算 433
54
顺 54
6
序
6
0
3
低输
1
出
6
顺
6
高序
所以:(3467)10 =(6613)8
28
算法思想:当N>0时重复1,2 1. 若 N≠0,则将N % r 压入栈s中 ,执行2;
若N=0,将栈s的内容依次出栈, 算法结束。 2. 用N / r 代替 N
29
【算法3-10】数制转换算法一
队满时 m=maxsize,队空时m=0
front rear
data
0
a1
1
a2
2
a3
…
…
n-1
an
…
…
Max-1
Top=-1,B、A出栈
13
顺序栈的主要运算
• 特殊情况表示: • 栈空:top == -1 • 栈满:top == maxsize-1
• 运算实现: • 入栈:若栈不满 s->top++ ; • 出栈:若栈不空 s->top-- ;
14
⑴ 置空栈
【算法3-1】栈的初始化算法 SeqStack *Init_SeqStack(){
若空则出错 (2)获取栈顶元素 x (3)栈顶指针减1
int Pop_SeqStack(SeqStack *s,DataType x){ if (Empty_SeqStack(s)) return 0; //栈空不能出栈,返回错误代码0 else { x=s->data[s->top]; //保存栈顶元素值
typedef struct {
datatype data[maxsize];
第3章 栈和队列
{ x=N%2; Push(&S, x); N=N/2; }
while(!IsEmpty(S)) { Pop(&S,&x); printf(“%d”,x); } }
返回主目录
2. 括号匹配问题
思想:在检验算法中设置一个栈,若读入的是左括号, 则直接入栈,等待相匹配的同类右括号;若读入的是 右括号,且与当前栈顶的左括号同类型,则二者匹配, 将栈顶的左括号出栈,否则属于不合法的情况。另外, 如果输入序列已读尽,而栈中仍有等待匹配的左括号, 或者读入了一个右括号,而栈中已无等待匹配的左括 号,均属不合法的情况。当输入序列和栈同时变为空 时,说明所有括号完全匹配。
注意:链栈在使用完毕时,应该释放其空间。
返回主目录
用C语言定义的链栈结构
typedef struct node
{
StackElementType data;
struct node *next;
}LinkStackNode;
typedef LinkStackNode *LinkStack;
返回主目录
进OVS
读字符W Y N W是操作符 Y OPTR栈空 N W优先级≤OPTR栈 顶优先级 Y 结束 进OPTR栈 W=„#‟‟ Y
N
N Y
退OVS顶、次顶,OPTR顶 将T(i)=>OVS新顶
返回主目录
2) 算术表达式处理规则 (1) 规定优先级表;
(2) 设置两个栈:OVS(运算数栈)和OPTR(运算符 栈);
返回主目录
算法:
void BracketMatch(char *str) {Stack S; int i; char ch; InitStack(&S); For(i=0; str[i]!='\0'; i++) {switch(str[i]) {case '(': case '[': case '{': Push(&S,str[i]); break; {GetTop (&S,&ch); if(Match(ch,str[i])) Pop(&S,&ch); else { printf("\n对应的左右括号不同类!"); return;} } }/*switch*/ }/*for*/ if(IsEmpty(S)) printf("\n括号匹配!"); else printf("\n左括号多余!"); }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
初始条件:栈S已存在。 操作结果:返回S的元素个数,即栈的长度。 孙克雷制作
栈的基本操作
GetTop(S,&e)
初始条件:栈S已存在且非空。 操作结果:用e返回S的栈顶元素。 ClearStack(&S) 初始条件:栈S已存在。 操作结果:将S清为空栈。 Push(&S,e) 初始条件:栈S已存在。 操作结果:插入元素e为新的栈顶元素。 Pop(&S,&e) 初始条件:栈S已存在且非空。 孙克雷制作 操作结果:删除S的栈顶元素,并用e返回其值。
N%8 4
scanf ("%d",&N);
while (N) { Push(S, N % 8);
21
2 0
0 输 出 5 顺 序 2
N = N/8; }
while (!StackEmpty(S)) { Pop(S,e); printf ( "%d", e ); } } // conversion 孙克雷制作
4 3
J6 5
4 3
2 J9
0 1
J7 J8
2
队满
如何判断循环队列 队空、队满都有 队空、队满?
Q.front=Q.rear
Q.rear
4 3
5 2
0 1
Q.front
队空 孙克雷制作
解决方法
1. 另设一个标志位让删除动作使其为1,插入动作使其为0, 则可识别当前Q. front= Q. rear; 2. 用一个计数器记录队列中元素的总数(即队列长度); 3. 少用一个存储单元,队满条件:Q.front=Q.rear+1。
孙克雷制作
有关循环队列操作说明
队头、队尾指针加1,可用取模(余数)运算实现。
队头指针进1: Q.front = (Q.front+1) %MAXSIZE; 队尾指针进1: Q.rear = (Q.rear+1) % MAXSIZE;
队列初始化:Q.front = Q.rear = 0; 队空条件:Q.front == Q.rear; 队满条件:(Q.rear+1) % MAXSIZE == Q.front; 队列长度:(Q.rear-Q.front+MAXSIZE)%MAXSIZE。
DestroyQueue(&Q)
初始条件:队列Q已存在。 操作结果:队列Q被销毁,不再存在。
QueueEmpty(Q)
初始条件:队列Q已存在。 操作结果:若Q为空返回TRUE,否则返回FALSE。
QueueLength(Q)
初始条件:队列Q已存在。
操作结果:返回Q的元素个数,即队列的长度。 孙克雷制作
(a1, a2, ... , ai -1, ai , ai+1, …, an )
删除 插入
孙克雷制作
3.1.1 栈的特性和定义
栈的特点 出栈 进栈 栈顶 an 第一个进栈的元素在栈底; 最后一个进栈的元素在栈顶; a2 栈底 a1 第一个出栈的元素为栈顶元素; 最后一个出栈的元素为栈底元素。 孙克雷制作
孙克雷制作
顺序栈的基本操作
初始化操作算法
Status InitStack(SqStack &S) {
S.base=( SElemType * )malloc(STACK_INIT_SIZE * sizeof(SElemType));
//为顺序栈动态分配存储空间
S.top=S.base; return OK; } //InitStack
后进先出
(LIFO)
3.1.2 栈的抽象数据类型
InitStack(&S)
操作结果:构造一个空栈S。
DestroyStack(&S)
初始条件:栈S已存在。 操作结果:栈S被销毁。
StackEmpty(S)
初始条件:栈S已存在。 操作结果:若栈S为空返回TRUE,否则FALSE。
StackLength(S)
int rear;
} SqQueue;
//队尾指针,指向队尾元素的下一个位置
孙克雷制作
此时又有J7入队,该怎么办? 3.5.1 队列的顺序存贮结构
初始状态为front=rear=0;每插入一个元素尾指针增1,每 删除一个元素,头指针增1。
Q.rear
5
4 3 Q.rear
5
4 3 Q.rear
5
4 3
3.3 栈的链式存储结构及其操作
不带头结点的单链表,其插入和删除操作仅限制在表头位 置上进行。链表的头指针即栈顶指针。
Data next
S 在前面学习了线性链表的 插入、删除操作算法,不 难写出链式栈初始化、进 栈、出栈等操作的算法。
an an-1
栈顶
an-2
a1
ቤተ መጻሕፍቲ ባይዱ
孙克雷制作
栈底
3.4 队列的基本概念
什么叫“假溢出” ?如何解决?
在顺序队中,当尾指针已经到了数组的上界,不能再有 入队操作,但其实数组中还有空位置,这就叫“假溢出”。 解决假溢出的途径———采用循环队列 孙克雷制作
3.5.2 循环队列
将顺序队列臆造为一个环状的空间。
J5 J5 J4 Q.front J6 5 Q.front 0 J7 1 Q.rear Q.rear J4
• 当栈非空时,top的位置是指向当前栈顶元素的下一个
位置
孙克雷制作
顺序栈的图示
99
n n-1 n-2 1 0
约定栈顶指针指向栈顶
元素的下一个位置 an an-1 a2 a1
S.top S.base
当栈用顺序结构存储时, 栈的基本操作如建空栈、进 栈、出栈等如何实现?
孙克雷制作
顺序栈的操作图示
初始条件:Q为非空队列。 操作结果:删除Q的队头元素,并用e返回其值。 孙克雷制作
3.5 队列的顺序存储结构及其操作
队列的顺序存贮结构 #define MAXSIZE 100 //最大队列长度
typedef struct{
QElemType *base; //初始化时动态分配存储空间的基址 int front; //队头指针,指向队头元素
什么是队列? 队列是限定仅能在表头进行删除,表尾进行插入的线 性表,能进行插入的一端称为队尾,能进行删除的一端称为 队头。称插入操作为入队,删除操作为出队。 (a1, a2, ... , ai -1, ai , ai+1, …, an ) 删除 插入
孙克雷制作
3.4.1 队列的定义及特性
出队列
5
4 3
J6
J5 J4
2
Q.rear 1 0
2
1 0 Q.front
J3
J2 J1 Q.front
2
1 0
J3
2 Q.front 1
0
J3
Q.front
空队列
J1,J2和J3相 继入队列
J1,J2相继出 队列
J4,J5,J6相继 孙克雷制作 入队列
有关操作具体说明
进队时,将新元素按Q.rear 指示位置加入,再将队尾指针 增1, Q.rear = Q.rear + 1 。 出队时,将下标为Q.front 的元素取出,再将队头指针增1 , Q.front = Q.front + 1 。 队满时再进队将溢出出错;队空时再出队作队空处理。上 图为“假溢”。
孙克雷制作
3.2.3 栈的应用举例
数制转换 N = (N / d)×d + N % d (d代表d进制数)
void conversion 例如:(1348)10 = (2504)8 ,其运算过程如下: ( ) { InitStack(S);
N 计 算 168 顺 21 序 2 1348
N/8 168
第3章 栈和队列
学习要点
理解栈和队列的基本概念和各种存储结构。
掌握栈和队列的各种运算方法。
孙克雷制作
3.1 栈的基本概念
什么是栈? 栈是限定仅能在表的一端进行插入、删除操作的线性表
。能进行插入和删除的一端为栈顶(top),另一端为栈底 (bottom)。 称插入操作为进栈,删除操作为出栈。进栈出栈操作只 能在栈顶进行。
1 0
S.top S.base
孙克雷制作
顺序栈的基本操作
出栈操作算法 Status Pop(SqStack &S , ElemType &e) { if (S.top==S.base) e=* - - S.top; return OK; } //Pop return ERROR; //栈空 // - - S.top; e=*S.top
} //Push
孙克雷制作
顺序栈的基本操作
出栈操作Pop(SqStack &S, ElemType &e ) 功能:栈顶元素退栈,并用e 返回
99 n n-1 n-2 99 n 栈顶元素进栈 n-1 n-2
e an an-1 100 a2 a1
an
an an-1 a2 a1
100
1 0
S.top S.base
取栈顶元素操作GetTop(SqStack S, SElemType &e) 功能:取栈顶元素,并用e返回
99 n n-1 n-2 1 0
an an-1 100 a2 a1
S.top S.base
e
an
孙克雷制作
顺序栈的基本操作
取栈顶元素操作算法 Status GetTop (SqStack S , SElemType &e) { if (S.top==S.base) e=*(S.top -1); return OK; } //GetTop return ERROR; //栈空