栈及其应用PPT课件
合集下载
数据结构——用C语言描述(第3版)教学课件第3章 栈和队列

if(S->top==-1) /*栈为空*/
return(FALSE);
else
{*x = S->elem[S->top];
return(TRUE);
}
返回主目录}[注意]:在实现GetTop操作时,也可将参数说明SeqStack *S 改为SeqStack S,也就是将传地址改为传值方式。传 值比传地址容易理解,但传地址比传值更节省时间、 空间。
返回主目录
算法:
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 '{':
3.1.3 栈的应用举例
1. 括号匹配问题
思想:在检验算法中设置一个栈,若读入的是左括号, 则直接入栈,等待相匹配的同类右括号;若读入的是 右括号,且与当前栈顶的左括号同类型,则二者匹配, 将栈顶的左括号出栈,否则属于不合法的情况。另外, 如果输入序列已读尽,而栈中仍有等待匹配的左括号, 或者读入了一个右括号,而栈中已无等待匹配的左括 号,均属不合法的情况。当输入序列和栈同时变为空 时,说明所有括号完全匹配。
return(TRUE);
}
返回主目录
【思考题】
如果将可利用的空闲结点空间组织成链栈来管理,则申 请一个新结点(类似C语言中的malloc函数)相当于链 栈的什么操作?归还一个无用结点(类似C语言中的 free函数)相当于链栈的什么操作?试分别写出从链栈 中申请一个新结点和归还一个空闲结点的算法。
数据结构 课件 第3章 栈

实用数据结构基础
第3章 栈
第 3 章 栈
知
识点
栈的定义和特点 栈的基本运算和算法 栈的典型应用
难
点
后缀表达式的算法 数制的换算 利用本章的基本知识设计相关的应用问题
要
求
掌握栈的特点 掌握栈的基本运算 熟悉栈的各种实际应用 能设计栈应用的典型算法 了解栈的运算时间复杂度分析
第3章 目录
2.顺序栈运算的基本算法 (1)置空栈 首先建立栈空间,然后初始化栈顶指针。 SeqStack *Snull( ) { SeqStack *s; s=new (SeqStack);
// 在C语言中用s=malloc(sizeof(SeqStack)) ;
s->top= –1; return s; }
3-1 栈的定义与运算 3-2 栈的存储和实现 3-3 栈的应用举例 小 结 验证性实验3: 栈子系统 自主设计实验3:后缀表达式求值 单元练习3
3-1 栈的定义和运算
3-1-1 栈(Stack)的定义
1. 栈的定义 栈是限制在表尾进行插入和删除的线性表。 进栈 出栈
an …… a3 a2 a1
图3-1栈的 示意图
3-3.
3-3-1 数制转换
栈的应用举例
数值进位制的换算是计算机实现计算和处理的 基本问题。比如将十进制数N转换为j进制的数,其 解决的方法很多,其中一个常用的算法是除j取余法。 将十进制数每次除以j,所得的余数依次入栈,然后 按“后进先出”的次序出栈便得到转换的结果。 其算法原理是: N =(N / j)* j + N % j
由于栈的操作只能在栈顶进行的,所以用链表的头部做
栈顶是最合适的。链栈结构如图3-4所示。
第3章 栈
第 3 章 栈
知
识点
栈的定义和特点 栈的基本运算和算法 栈的典型应用
难
点
后缀表达式的算法 数制的换算 利用本章的基本知识设计相关的应用问题
要
求
掌握栈的特点 掌握栈的基本运算 熟悉栈的各种实际应用 能设计栈应用的典型算法 了解栈的运算时间复杂度分析
第3章 目录
2.顺序栈运算的基本算法 (1)置空栈 首先建立栈空间,然后初始化栈顶指针。 SeqStack *Snull( ) { SeqStack *s; s=new (SeqStack);
// 在C语言中用s=malloc(sizeof(SeqStack)) ;
s->top= –1; return s; }
3-1 栈的定义与运算 3-2 栈的存储和实现 3-3 栈的应用举例 小 结 验证性实验3: 栈子系统 自主设计实验3:后缀表达式求值 单元练习3
3-1 栈的定义和运算
3-1-1 栈(Stack)的定义
1. 栈的定义 栈是限制在表尾进行插入和删除的线性表。 进栈 出栈
an …… a3 a2 a1
图3-1栈的 示意图
3-3.
3-3-1 数制转换
栈的应用举例
数值进位制的换算是计算机实现计算和处理的 基本问题。比如将十进制数N转换为j进制的数,其 解决的方法很多,其中一个常用的算法是除j取余法。 将十进制数每次除以j,所得的余数依次入栈,然后 按“后进先出”的次序出栈便得到转换的结果。 其算法原理是: N =(N / j)* j + N % j
由于栈的操作只能在栈顶进行的,所以用链表的头部做
栈顶是最合适的。链栈结构如图3-4所示。
大学数据结构课件--第3章 栈和队列

top top 栈空 F E D C B A
栈满 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
栈满 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
数据结构栈和队列ppt课件

栈的运用 例3.1 将一个十进制正整数N转换成r进制的数
N 〕
1835
229
28
3
N / 8 〔整除〕 N % 8〔求余
229
3
低
28
5
3
4
0
3
高
❖例3.2 算术表达式中括号匹配的检查
❖用栈来实现括号匹配检查的原那么是,对表达式从左 到右扫描。
❖〔1〕当遇到左括号时,左括号入栈;
❖〔2〕当遇到右括号时,首先检查栈能否空,假设栈 空,那么阐明该“右括弧〞多余;否那么比较栈顶左 括号能否与当前右括号匹配,假设匹配,将栈顶左括 号出栈,继续操作;否那么,阐明不匹配,停顿操作 。
❖在顺序栈上实现五种根本运算的C函数 ❖〔3〕入栈 ❖int push (SeqStack *s, DataType x) ❖{ if (s->top==MAXSIZE-1) /*栈满不能入栈*/ ❖{ printf("overflow"); ❖return 0; ❖} ❖ s->top++; ❖ s->data[s->top]=x; ❖ return 1; ❖}
链队列及运算的实现
采用链接方法存储的队列称为链队列〔Linked Queue〕
采用带头结点的单链表来实现链队列,链队列中 的t结ype点de类f st型ruc与t N单od链e 表一样。将头指针front和尾指针 re{arD封at装aTy在pe一da个ta;构造体中,链队列用C言语描画如 下:struct Node *next;
❖只设了一个尾指针r ❖头结点的指针,即r->next ❖队头元素的指针为r->next->next ❖队空的断定条件是r->next==r
数据结构ppt课件

二叉树的性质
二叉树具有五种基本形态,即空二叉树、只有一个根节点的二叉树、只有左子树或右子 树的二叉树、以及左右子树均有的二叉树。此外,二叉树还具有一些重要性质,如二叉
树的第i层最多有2^(i-1)个节点(i>=1),深度为k的二叉树最多有2^k-1个节点 (k>=1)等。
二叉树的遍历算法
先序遍历
先访问根节点,然后遍 历左子树,最后遍历右
05
图论基础及图的存储结构
图论基础概念介绍
图的基本概念
由顶点(Vertex)和边(Edge)组成的数 据结构,表示对象及其之间的关系。
图的遍历
通过某种方式访问图中所有顶点的过程, 常见的遍历算法有深度优先遍历(DFS)和 广度优先遍历(BFS)。
有向图与无向图
根据边是否有方向,图可分为有向图和无 向图。
时间复杂度
平均时间复杂度和最坏时 间复杂度均为O(n)。
适用场景
适用于数据量较小或数据 无序的情况。
查找算法设计之二分查找法
算法思想
在有序数组中,取中间元素与目标元素比较,若相等则查找成功;若目标元素小于中间元素, 则在左半部分继续查找;若目标元素大于中间元素,则在右半部分继续查找。
时间复杂度
平均时间复杂度和最坏时间复杂度均为O(log n)。
连通图与连通分量
在无向图中,任意两个顶点之间都存在路 径,则称该图是连通图;否则,称该图的 极大连通子图为连通分量。
顶点的度
在无向图中,顶点的度是与该顶点相关联 的边的数目;在有向图中,顶点的度分为 入度和出度。
图的存储结构之邻接矩阵法
邻接矩阵表示法
用一个二维数组表示图中顶点之 间的关系,若顶点i与顶点j之间 存在一条边,则数组元素值为1
二叉树具有五种基本形态,即空二叉树、只有一个根节点的二叉树、只有左子树或右子 树的二叉树、以及左右子树均有的二叉树。此外,二叉树还具有一些重要性质,如二叉
树的第i层最多有2^(i-1)个节点(i>=1),深度为k的二叉树最多有2^k-1个节点 (k>=1)等。
二叉树的遍历算法
先序遍历
先访问根节点,然后遍 历左子树,最后遍历右
05
图论基础及图的存储结构
图论基础概念介绍
图的基本概念
由顶点(Vertex)和边(Edge)组成的数 据结构,表示对象及其之间的关系。
图的遍历
通过某种方式访问图中所有顶点的过程, 常见的遍历算法有深度优先遍历(DFS)和 广度优先遍历(BFS)。
有向图与无向图
根据边是否有方向,图可分为有向图和无 向图。
时间复杂度
平均时间复杂度和最坏时 间复杂度均为O(n)。
适用场景
适用于数据量较小或数据 无序的情况。
查找算法设计之二分查找法
算法思想
在有序数组中,取中间元素与目标元素比较,若相等则查找成功;若目标元素小于中间元素, 则在左半部分继续查找;若目标元素大于中间元素,则在右半部分继续查找。
时间复杂度
平均时间复杂度和最坏时间复杂度均为O(log n)。
连通图与连通分量
在无向图中,任意两个顶点之间都存在路 径,则称该图是连通图;否则,称该图的 极大连通子图为连通分量。
顶点的度
在无向图中,顶点的度是与该顶点相关联 的边的数目;在有向图中,顶点的度分为 入度和出度。
图的存储结构之邻接矩阵法
邻接矩阵表示法
用一个二维数组表示图中顶点之 间的关系,若顶点i与顶点j之间 存在一条边,则数组元素值为1
堆栈知识详解(简单易懂)ppt课件

– 公式化描述 – 链表描述
• 堆栈的应用
– 括号匹配、汉诺塔、火车车厢重排 – 迷宫、开关盒布线、离线等价类
信息技术科学学院
最新编辑ppt
7
公式化描述:继承线性表
template<class T>
线性表尾部作为栈顶
class Stack : private LinearList <T> {
// LIFO objects
到表尾
{Insert(Length(), x); return *this;}
Stack<T>& Pop(T& x)
{Delete(Length(), x);
return *this;} };
出栈——提取最后一个元素
信息技术科学学院
最新编辑ppt
9
实现方法分析
• IsFull需要获取数组大小
– 方法一 将类LinearList的成员MaxSize变为protected类型
第5章 堆栈
----后进先出:一种操作受限的线性表
信息技术科学学院
主要内容
• 堆栈的定义 • 堆栈的描述
– 公式化描述 – 链表描述
• 堆栈的应用
– 括号匹配、汉诺塔、火车车厢重排 – 迷宫、开关盒布线、离线等价类
信息技术科学学院
最新编辑ppt
2
堆栈定义
• 堆栈(stack)是一个线性表, 其插入和删除操作都在表的同一端进行,这 端被称为栈顶(top), 另一端被称为栈底(bottom)
• LIFO
push
E
Last in, F栈ir顶st out
top E
x E
栈顶
DD
• 堆栈的应用
– 括号匹配、汉诺塔、火车车厢重排 – 迷宫、开关盒布线、离线等价类
信息技术科学学院
最新编辑ppt
7
公式化描述:继承线性表
template<class T>
线性表尾部作为栈顶
class Stack : private LinearList <T> {
// LIFO objects
到表尾
{Insert(Length(), x); return *this;}
Stack<T>& Pop(T& x)
{Delete(Length(), x);
return *this;} };
出栈——提取最后一个元素
信息技术科学学院
最新编辑ppt
9
实现方法分析
• IsFull需要获取数组大小
– 方法一 将类LinearList的成员MaxSize变为protected类型
第5章 堆栈
----后进先出:一种操作受限的线性表
信息技术科学学院
主要内容
• 堆栈的定义 • 堆栈的描述
– 公式化描述 – 链表描述
• 堆栈的应用
– 括号匹配、汉诺塔、火车车厢重排 – 迷宫、开关盒布线、离线等价类
信息技术科学学院
最新编辑ppt
2
堆栈定义
• 堆栈(stack)是一个线性表, 其插入和删除操作都在表的同一端进行,这 端被称为栈顶(top), 另一端被称为栈底(bottom)
• LIFO
push
E
Last in, F栈ir顶st out
top E
x E
栈顶
DD
栈课件浙教版高中信息技术选修1

栈
新课导入
装置只有一端是开放的,所有的操作都只能在这开放的一端进行。
数据具有“先进后出、后进先出”的特征,可采用“栈”这种数据结构。
栈
栈是一种后进先出的线性表,仅允许在表的一端进行插入或删除操作。 进行插入或删除操作的一端称为栈顶,位于栈顶位置的元素称为栈顶元素;另一端称为栈底,位于栈底 位置的元素称为栈底元素。
备注 初始化各项数据
从左往右逐步处理数学表达式:若为 左括号则入栈;若为右括号则与栈顶 指针进行匹配。
数据合并问题
程序 if top > 0: # 栈中还有剩余元素
flag = False if flag:
print("括号匹配") else:
print("括号不匹配")
备注 栈中还有剩余元素,即左括号数量大于右括号。
数据合并问题
程序
st = [""]*100 # 初始化 top = -1 # 初始化为空栈 flag = True # 标记是否有不匹配的情况 s = input("请输入数学表达式:")
for i in range(len(s)): if s[i] == "(": # 左括号入栈 top += 1 st[top] = s[i] elif s[i] == ")": # 右括号与栈顶元素比较 if top == -1: flag = False break else: top -= 1
2. 一个栈的入栈序列是1,2,3,4,5,其出栈序列为s1,s2,s3,s4,s5,若s2是3,则s1不可能是( D )
A. 1
B. 2
C. 4
D. 5
新课导入
装置只有一端是开放的,所有的操作都只能在这开放的一端进行。
数据具有“先进后出、后进先出”的特征,可采用“栈”这种数据结构。
栈
栈是一种后进先出的线性表,仅允许在表的一端进行插入或删除操作。 进行插入或删除操作的一端称为栈顶,位于栈顶位置的元素称为栈顶元素;另一端称为栈底,位于栈底 位置的元素称为栈底元素。
备注 初始化各项数据
从左往右逐步处理数学表达式:若为 左括号则入栈;若为右括号则与栈顶 指针进行匹配。
数据合并问题
程序 if top > 0: # 栈中还有剩余元素
flag = False if flag:
print("括号匹配") else:
print("括号不匹配")
备注 栈中还有剩余元素,即左括号数量大于右括号。
数据合并问题
程序
st = [""]*100 # 初始化 top = -1 # 初始化为空栈 flag = True # 标记是否有不匹配的情况 s = input("请输入数学表达式:")
for i in range(len(s)): if s[i] == "(": # 左括号入栈 top += 1 st[top] = s[i] elif s[i] == ")": # 右括号与栈顶元素比较 if top == -1: flag = False break else: top -= 1
2. 一个栈的入栈序列是1,2,3,4,5,其出栈序列为s1,s2,s3,s4,s5,若s2是3,则s1不可能是( D )
A. 1
B. 2
C. 4
D. 5
数据结构ppt课件完整版

针对有序数据集合,每次通过中间元素将 待查找区间缩小为之前的一半,直到找到 元素或区间为空。
哈希查找
树形查找
通过哈希函数将数据映射到哈希表中,实 现快速查找。
如二叉搜索树、平衡树等,通过树形结构实 现高效查找。
排序算法分类及实现原理
插入排序
将待排序元素逐个插入到已排序序列中,直到所有元素均插入完毕。
由n(n>=0)个具有相同类型 的数据元素(结点)a1,a2,
...,an组成的有序序列。
同一性
每个元素必须是同一类型的数 据。
有序性
元素之间具有一对一的前驱和 后继关系,即除首尾元素外, 每个元素都有一个前驱和一个 后继。
可变性
线性表的长度可变,即可以插 入或删除元素。
顺序存储结构与链式存储结构比较
定义
用一段连续的存储单元依次存储线性 表的数据元素。
优点
可以随机存取表中任一元素,且存取 时间复杂度为O(1)。
顺序存储结构与链式存储结构比较
• 缺点:插入和删除操作需要移动大量元素,时间 复杂度高;需要预先分配存储空间,容易造成空 间浪费。
顺序存储结构与链式存储结构比较
定义
用一组任意的存储单元存储线性 表的数据元素(这组存储单元可 以是连续的,也可以是不连续的
查找操作
查找指定元素的位置。
遍历操作
访问线性表中的每个元素。
销毁操作
释放线性表占用的存储空间。
03
栈和队列
栈定义及特点
栈(Stack)是一种特殊的线性数据结构,其数据的存 取遵循后进先出(LIFO, Last In First Out)的原则。 栈的特点
具有记忆功能,能保存数据的状态。
栈的基本操作包括入栈(push)、出栈(pop)、查 看栈顶元素(top)等。 只能在栈顶进行数据的插入和删除操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
.
特别的,不含任何元素的栈称为空栈。
二、栈的实现 1.栈的顺序存储结构
我们称用顺序结构存储的栈为顺序栈(array-based stack),即:利用连续的存储单元依次记录 栈的所有元素。一般来说,使用一维数组B存储栈的所有元素,变量top记录栈的大小,将s[1]叫作 为栈底,s[top]为栈顶。顺序栈Stack定义如下: TYPE Stack =record
一、栈的定义 从上面的例子,我们可以看出,栈(Stack)是一种特殊的线性表,它的特殊之
处在说,栈的操作是按后进 先出的顺序处理数据,因此栈又称后进先出表(Lastn First Out,LIFO)。
对于一个栈来说,我们习惯上称它的可操作端为栈顶 (Top),另一端为栈底 (Bottom)。设栈S=(a1,a2,···,an),a1端为栈底,an端为栈顶,则有: 1.插入一个元素an+1后,栈更新为S=(a1, a2,...,an,an+1) 2.从栈中删除一个元素后,栈更新为S=(a1,a2,,...,an-1)
S=D1 op1 D2 op2 D3 op3 ..Di opi... Dn-1 opn-1 Dn,这里Di为操作数,opi 为运算符,i=l, 2,...,n-l,由此,我们得到如下算法:
(1)对S进行扫描,从opi中找一个最高优先级别的运算符进行操作 并将Di-1=Di-1 opi-1 Di。删除opi-1和Di.
.
【例4】利用栈实现算术表达式求值 编写一个包含有“+”、“-”、“,”、“/”、“(”、“)”等运算符的表达式,计 算出该表达式的数值。
例如,3*(5-2)+7=3*3+7=9+7=16。
[分析] 对于给定的表达式计算,有一个运算符优先计算的问题,即“先算括号内,再算
括号外,先算乘除,再算加减,同一级别的算符从左到右进行运算”等。因此, 我们在计算过程中确定优先规则至关重要。对于任意一个表达式,我们可以将之 抽象成以下形式:
[例2]括弧匹配检验:假设表达式中允许包含两种括号即圆括号和方括号,其嵌套的 顺序随意,如([]())或[([][])]等为正确的匹配,[(])或([]()或()))均为错误的匹配。现在 的问题是,要求检验一个给定表达式中的括弧是否正确匹配?
看是否匹配,具体是看每个左括号是否有一个右括号跟它匹配。而且括号可 以嵌套,要检查外层括号是否匹配,必须先检查内层的括号是否匹配,也就是 先遇到的左括号后处理,这时,堆栈又有了用武之地。具体做法是遇到左括号 就入栈,遇到右括号就出栈并判断是否匹配。当括号串全部处理完毕,而且堆 栈为空,则是合法的,其他情况都是非法的。
(2)如果S 只有一个数,那么S 为答案。否则,转到第一步继续操作。
上述算法,要扫描S 表达式n-1 次,每对S 做一次扫描,需要对S 的每个字符作 判断,如果S用链表存储,那么可以避免删除后的移动。因此时间复杂度为O(n2)。
栈及其应用
安庆四中
范江文
.
在现实生活中,常常会出现一些特殊的线性结构的情形。例如,我们在洗碗时, 总是将最后洗的碗叠在当前一列碗的最上面,而用的时候总是将最上面的碗,也 就是最后洗的碗先拿去用。类似的,储蓄罐、瓷坛等只有一个开口的容器存放物 品时,都是具有最后放的东西最先倒出来的特性。
图1是某个火车站的车厢调度储存室,进站的火车厢只能从左端进入,并从左端 出站。这个特殊的调度室也具有一端封闭的特性,因此最后调入的火车厢肯定最 先调出。我们将具有"先进后出"特性的特殊装置,称之为栈。
top :integer; {栈顶指针} s: array [1.. Maxlength] of elemtype;{记录栈中元素的线性表) Procedure init;{初始化栈} function push (var st:stack;a:elemtype):boolean; {压栈,若栈不满,则在栈顶插入元素a,返回 true;否则返回false} function pop(stack):elemtype; {弹栈,若栈不为空则删除栈顶元素并返回元素值;否则返回NULL} procedure stack.init; Top<-0 {栈置空} function push(var st:stack;a:elemtype):boolean; If top<maxlength then begin inc(st.top);st.s[st.top]:=a; end else push:=fasle ; function pop():elemtype; If st.top=0 then 栈为空 else pop:=st.s[st.top]; dec(st.top);
.
[例3]给定N(N<=100000)个数,找出每个数后面第一个比它大的数的编号。没有输出0。 input: 3 2 6 1 1 2 output:3 3 0 6 6 0
先把题目要求的那个编号叫做后继编号。数列是按照从左往右的顺序编号的,在遇 到比它大的元素之前,是无法知道这个元素的后继编号的。并且是离后继编号元素最 近的元素先求出来,堆栈的用武之地又出现了。维护一个栈,栈里面存储所有尚未确 定后继编号的数,显然这个栈里的数是单调递减的。初始栈里没有数(或者有一个,就 是第一个数),然后对于每一个尚未处理的数,用它和栈顶的数比较,如果小于等于栈 顶,就入栈,如果大,就把栈顶的数出栈(这时候栈顶的数的后继编号),重复这一过程 直到这个数入栈或者栈为空(然后再入栈),接着继续处理剩下的数。
.
三、栈的应用
(一)堆栈具有先进后出(后进先出)的特性,凡是具有这种特性的题目我们都可以用
堆栈来试一试。
[例1]编制一个满足下列要求的程序:对于输人的任意一个非负十进制整数,打印输 出与其等值的八进制数。例如:(1348)10=(2504)8
这八进制的各个数位产生的顺序是从低位到高位的,而打印输出的顺序,一 般来说应从高位到低位,这恰好和计算过程相反。所以,堆栈的用武之地出来 了。具体做法就是把求到的数位先依次入栈,然后再依次出栈。
特别的,不含任何元素的栈称为空栈。
二、栈的实现 1.栈的顺序存储结构
我们称用顺序结构存储的栈为顺序栈(array-based stack),即:利用连续的存储单元依次记录 栈的所有元素。一般来说,使用一维数组B存储栈的所有元素,变量top记录栈的大小,将s[1]叫作 为栈底,s[top]为栈顶。顺序栈Stack定义如下: TYPE Stack =record
一、栈的定义 从上面的例子,我们可以看出,栈(Stack)是一种特殊的线性表,它的特殊之
处在说,栈的操作是按后进 先出的顺序处理数据,因此栈又称后进先出表(Lastn First Out,LIFO)。
对于一个栈来说,我们习惯上称它的可操作端为栈顶 (Top),另一端为栈底 (Bottom)。设栈S=(a1,a2,···,an),a1端为栈底,an端为栈顶,则有: 1.插入一个元素an+1后,栈更新为S=(a1, a2,...,an,an+1) 2.从栈中删除一个元素后,栈更新为S=(a1,a2,,...,an-1)
S=D1 op1 D2 op2 D3 op3 ..Di opi... Dn-1 opn-1 Dn,这里Di为操作数,opi 为运算符,i=l, 2,...,n-l,由此,我们得到如下算法:
(1)对S进行扫描,从opi中找一个最高优先级别的运算符进行操作 并将Di-1=Di-1 opi-1 Di。删除opi-1和Di.
.
【例4】利用栈实现算术表达式求值 编写一个包含有“+”、“-”、“,”、“/”、“(”、“)”等运算符的表达式,计 算出该表达式的数值。
例如,3*(5-2)+7=3*3+7=9+7=16。
[分析] 对于给定的表达式计算,有一个运算符优先计算的问题,即“先算括号内,再算
括号外,先算乘除,再算加减,同一级别的算符从左到右进行运算”等。因此, 我们在计算过程中确定优先规则至关重要。对于任意一个表达式,我们可以将之 抽象成以下形式:
[例2]括弧匹配检验:假设表达式中允许包含两种括号即圆括号和方括号,其嵌套的 顺序随意,如([]())或[([][])]等为正确的匹配,[(])或([]()或()))均为错误的匹配。现在 的问题是,要求检验一个给定表达式中的括弧是否正确匹配?
看是否匹配,具体是看每个左括号是否有一个右括号跟它匹配。而且括号可 以嵌套,要检查外层括号是否匹配,必须先检查内层的括号是否匹配,也就是 先遇到的左括号后处理,这时,堆栈又有了用武之地。具体做法是遇到左括号 就入栈,遇到右括号就出栈并判断是否匹配。当括号串全部处理完毕,而且堆 栈为空,则是合法的,其他情况都是非法的。
(2)如果S 只有一个数,那么S 为答案。否则,转到第一步继续操作。
上述算法,要扫描S 表达式n-1 次,每对S 做一次扫描,需要对S 的每个字符作 判断,如果S用链表存储,那么可以避免删除后的移动。因此时间复杂度为O(n2)。
栈及其应用
安庆四中
范江文
.
在现实生活中,常常会出现一些特殊的线性结构的情形。例如,我们在洗碗时, 总是将最后洗的碗叠在当前一列碗的最上面,而用的时候总是将最上面的碗,也 就是最后洗的碗先拿去用。类似的,储蓄罐、瓷坛等只有一个开口的容器存放物 品时,都是具有最后放的东西最先倒出来的特性。
图1是某个火车站的车厢调度储存室,进站的火车厢只能从左端进入,并从左端 出站。这个特殊的调度室也具有一端封闭的特性,因此最后调入的火车厢肯定最 先调出。我们将具有"先进后出"特性的特殊装置,称之为栈。
top :integer; {栈顶指针} s: array [1.. Maxlength] of elemtype;{记录栈中元素的线性表) Procedure init;{初始化栈} function push (var st:stack;a:elemtype):boolean; {压栈,若栈不满,则在栈顶插入元素a,返回 true;否则返回false} function pop(stack):elemtype; {弹栈,若栈不为空则删除栈顶元素并返回元素值;否则返回NULL} procedure stack.init; Top<-0 {栈置空} function push(var st:stack;a:elemtype):boolean; If top<maxlength then begin inc(st.top);st.s[st.top]:=a; end else push:=fasle ; function pop():elemtype; If st.top=0 then 栈为空 else pop:=st.s[st.top]; dec(st.top);
.
[例3]给定N(N<=100000)个数,找出每个数后面第一个比它大的数的编号。没有输出0。 input: 3 2 6 1 1 2 output:3 3 0 6 6 0
先把题目要求的那个编号叫做后继编号。数列是按照从左往右的顺序编号的,在遇 到比它大的元素之前,是无法知道这个元素的后继编号的。并且是离后继编号元素最 近的元素先求出来,堆栈的用武之地又出现了。维护一个栈,栈里面存储所有尚未确 定后继编号的数,显然这个栈里的数是单调递减的。初始栈里没有数(或者有一个,就 是第一个数),然后对于每一个尚未处理的数,用它和栈顶的数比较,如果小于等于栈 顶,就入栈,如果大,就把栈顶的数出栈(这时候栈顶的数的后继编号),重复这一过程 直到这个数入栈或者栈为空(然后再入栈),接着继续处理剩下的数。
.
三、栈的应用
(一)堆栈具有先进后出(后进先出)的特性,凡是具有这种特性的题目我们都可以用
堆栈来试一试。
[例1]编制一个满足下列要求的程序:对于输人的任意一个非负十进制整数,打印输 出与其等值的八进制数。例如:(1348)10=(2504)8
这八进制的各个数位产生的顺序是从低位到高位的,而打印输出的顺序,一 般来说应从高位到低位,这恰好和计算过程相反。所以,堆栈的用武之地出来 了。具体做法就是把求到的数位先依次入栈,然后再依次出栈。