数据结构课件-第3章-栈和队列.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《数据结构课件-第3章-栈和队列.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课件 队列
- 资源描述:
-
1、第三章第三章 栈和队列栈和队列【课前思考课前思考】1.什么是线性结构?2.你见过餐馆中一叠一叠的盘子吗?如果它们是按1,2,n 的次序往上叠的,那么使用时候的次序应是什么样的?3.在日常生活中,为了维持正常的社会秩序而出现的常见现象是什么?第三章第三章 栈和队列栈和队列 栈和队列与线性表相比,是限定性的线性表结构。栈的特点:栈必须按“后进先出”的规则进行操作队列特点:必须按“先进先出”的规则进行操作。插 入 删 除线性表:Insert(L,i,x)Delete(L,i)(1in+1)(1in)栈:Insert(L,n+1,x)Delete(L,n)队列:Insert(L,n+1,x)Delet
2、e(L,1)1.从“数据结构”的角度看,它们都是线性结构 即数据元素之间的关系相同。2.它们是完全不同的数据类型。除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的“限定”。如:线性表允许在表内任一位置进行插入和删除;栈只允许在表尾一端进行插入和删除;队列只允许在表尾一端插入,在表头一端删除。栈和队列与线性表对比:第三章第三章 栈和队列栈和队列3.1 栈栈 3.1.1 栈的类型定义栈的类型定义栈(栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。允许插入和删除的一端称作“栈顶(top)”不允许插入和删除的另一端称作栈底(bottom)通常称往栈顶插入元素的操作为“入栈”
3、,称删除栈顶元素的操作为“出栈”。栈被称为是一种“后进先出”的结构,又称LIFO(Last In First Out的缩写)表。如下图所示的铁路调度站 栈的类型定义如下:ADT Stack 数据对象:数据对象:Dai|ai ElemSet,i=1,2,.,n,n0 数据关系:数据关系:R1|ai-1 ,ai D,i=2,.,n 约定 an 端为栈顶,a1 端为栈底。基本操作:基本操作:InitStack(&S)操作结果:构造一个空栈 S。DestroyStack(&S)初始条件:栈 S 已存在。操作结果:栈 S 被销毁。ClearStack(&S)初始条件:栈 S 已存在。操作结果:将 S 清
4、为空栈。StackEmpty(S)初始条件:栈 S 已存在。操作结果:若栈 S 为空栈,则返回TRUE,否则 返回FALSE。StackLength(S)初始条件:栈 S 已存在。操作结果:返回栈 S 中元素个数,即栈的长度 GetTop(S,&e)初始条件:栈 S 已存在且非空。操作结果:用 e 返回S的栈顶元素。Push(&S,e)初始条件:栈 S 已存在。操作结果:插入元素 e 为新的栈顶元素。Pop(&S,&e)初始条件:栈 S 已存在且非空。操作结果:删除 S 的栈顶元素,并用 e 返回其值。StackTraverse(S,visit()初始条件:栈 S 已存在且非空,visit()
5、为元素的访问函数。操作结果:从栈底到栈顶依次对S的每个元素调用函数visit(),一旦visit()失败,则操作失败。ADT Stack 3.1栈栈3.1.2 栈的存储表示和操作的实现栈的存储表示和操作的实现栈也有两种存储表示:顺序存储和链式存储 顺序存储结构简称为顺序栈链式存储结构简称为链栈栈顶指针意为指示栈顶元素在栈中的位置,但它的值实际是栈中元素的个数,和顺序表中的 length 值的意义相同。一、顺序栈类型的定义一、顺序栈类型的定义/结构定义:结构定义:typedef struct elemType*base;/存储空间基址 int top;/栈顶指针 int stacksize;/允
6、许的最大存储空间以元素为单位 Stack;3.1栈栈3.1.2 栈的存储表示和操作的实现栈的存储表示和操作的实现/基本操作接口基本操作接口(函数声明函数声明):void InitStack(Stack&S,int maxsize);/构造一个最大存储容量为 maxsize 的空栈S。void DestroyStack(Stack&S);/销毁栈S,S 不再存在。void ClearStack(Stack&S);/将 S 置为空栈。bool StackEmpty(Stack S);/若栈 S 为空栈,则返回 TRUE,否则返回 FALSE int StackLength(Stack S);/返回
7、S的元素个数,即栈的长度。bool GetTop(Stack S,ElemType&e);/若栈不空,则用 e 返回S的栈顶元素,并返回TRUE;/否则返回 FALSE。bool Push(Stack&S,ElemType e);/若栈的存储空间不满,则插入元素 e 为新的栈顶 /元素,并返回 TRUE;否则返回FALSE。bool Pop(Stack&S,ElemType&e);/若栈不空,则删除S的栈顶元素,用e返回其值,/并返回TRUE;否则返回FALSE。void StackTraverse(Stack S,void(*visit(ElemType)/依次对S的每个元素调用函数 vis
8、it(),/一旦 visit()失败,则操作失败。void InitStack(Stack&S,int maxsize)/构造一个最大存储容量为构造一个最大存储容量为 maxsize 的空栈的空栈 Sif(maxsize=0)maxsize=MAXLISTSIZE;S.base=new SElemTypemaxsize;if(!S.base)exit(1);/存储分配失败S.stacksize=maxsize;S.top=0;/空栈中元素个数为0bool Push(Stack&S,ElemType e)/若栈的存储空间不满,则插入元素若栈的存储空间不满,则插入元素 e 为新的栈顶元素,为新的栈
9、顶元素,/并返回并返回 TRUE;否则返回;否则返回 FALSEif(S.top=S.stacksize)/栈已满,无法进行插入 return FALSE;*(S.base+S.top)=e;/插入新的元素+S.top;/栈顶指针后移return TRUE;在此只给出其中在此只给出其中4个函数的定义。个函数的定义。bool GetTop(Stack S,ElemType&e)/若栈不空,则用若栈不空,则用 e 返回返回S的栈顶元素,返回的栈顶元素,返回TRUE;/否则返回否则返回FALSEif(S.top=0)return FALSE;e=*(S.base+S.top-1);/返回非空栈中栈顶
10、元素S.baseS.top-1 return TRUE;bool Pop(Stack&S,ElemType&e)/若栈不空,则删除若栈不空,则删除S的栈顶元素,用的栈顶元素,用 e 返回其值,返回其值,/并返回并返回 TRUE;否则返回;否则返回 FALSE if(S.top=0)return FALSE;e=*(S.base+S.top-1);/返回非空栈中栈顶元素返回非空栈中栈顶元素-S.top;/栈顶指针前移栈顶指针前移return TRUE;Pop和 GetTop 不同仅在于多一句移动指针的语句。图中的顺序栈的最大容量为7,当前栈中元素个数为4,因此,我们也可认为栈顶指针总是指在栈顶元
11、素的后面一个位置上。用图表示顺序栈如下:abcdS.top S.stacksize 二、链栈链栈即为栈的链式存储结构。结点结构和单链表中的结点结构相同,链栈中不需要头结点,但链栈中指针的方向是从栈顶指向栈底的,正好和单链表是相反的。S.top栈顶栈底3.1栈栈3.1.2 栈的存储表示和操作的实现栈的存储表示和操作的实现结构定义:结构定义:typedef struct SLink top;/栈顶指针 int length;/栈中元素个数 Stack;只需对顺序栈的基本操作接口作两处改动,便可作为链栈的基本操作接口。其一:初始化时不需要“maxsize”的参数,因为它不需要事 先分配空间其二:在进
12、行入栈操作时,不需要顾忌栈的空间是否已 经被填满 链栈的基本操作链栈的基本操作void InitStack(Stack&S)/构造一个空栈构造一个空栈 SS.top=NULL;/设栈顶指针的初值为空 S.length=0;/空栈中元素个数为0/InitStackvoid Push(Stack&S,ElemType e)/在栈顶之上插入元素在栈顶之上插入元素 e 为新的栈顶元素为新的栈顶元素p=new LNode;/建新的结点建新的结点if(!p)exit(1);/存储分配失败存储分配失败p-data=e;p-next=S.top;/链接到原来的栈顶链接到原来的栈顶S.top=p;/移动栈顶指针
13、移动栈顶指针+S.length;/栈的长度增栈的长度增1/Pushbool Pop(Stack&S,SElemType&e)/若栈不空,则删除若栈不空,则删除S的栈顶元素,用的栈顶元素,用 e 返回其值,返回其值,/并返回并返回 TRUE;否则返回;否则返回 FALSEif(!S.top)return FALSE;else e=S.top-data;/返回栈顶元素 q=S.top;S.top=S.top-next;/修改栈顶指针 -S.length;/栈的长度减1 delete q;/释放被删除的结点空间 return TRUE;/Pop 3.2 栈的应用举例 3.2.1 数制转换数制转换 十
14、进制数N和其他d进制数的转换,解决方法很多,其中一个简单算法基于下列原理:N=(N div d)d+N mod d(其中:div 为整除运算,mod 为求余运算)例如:(1348)10=(2504)8 1348881684218820052计算过程输出顺序假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数。问题分析:问题很明确,就是要输出计算过程中所得到的各个八进制数位。然而从计算过程可见,这八进制的各个数位产生的顺序是从低位到高位的,而打印输出的顺序从高位到低位,这恰好和计算过程相反。因此,需要先保存在计算过程中得到的八进制数的各位,然后逆序输出
15、,因为它是按后进先出的规律进行的,所以用栈最合适。算法算法 3.1void conversion()/对于输入的任意一个非负十进制整数对于输入的任意一个非负十进制整数,输出与其等值的八进制数输出与其等值的八进制数InitStack(S);/构造空栈cin N;/输入一个十进制数while(N)Push(S,N%8);/余数入栈N=N/8;/非零商继续运算/whilewhile(!StackEmpty)/和“求余”所得相逆的顺序输出八进制的各位数 Pop(S,e);cout e;/while/conversion3.2.2 括弧匹配检验括弧匹配检验 假设表达式中允许包含两种括号:圆括号和方括号其
16、正确的匹配:如()或()等 错误的匹配:()或()或())等 现在的问题是,要求检验一个给定表达式中的括弧是否正确匹配?问题分析:方法可用“期待的急迫程度”这个概念来描述。即后出现的“左括弧”,它等待与其匹配的“右括弧”出现的“急迫”心情要比先出现的左括弧高。即:对“左括弧”来说,后出现的比先出现的“优先”等待检。对“右括弧”来说,每个出现的右括弧要去找在它之前“最后”出现的那个左括弧去匹配。显然,保存左括弧的结构用栈最合适。例如考虑下列括号序列:()1 2 3 4 5 6 7 8上面列举的三种错误匹配从“期待匹配”的角度描述即为:1来的右括弧非是所“期待”的;2来的是“不速之客”;3直到结束
17、,也没有到来所“期待”的。这三种情况对应到栈的操作即为:1和栈顶的左括弧不相匹配;2栈中并没有左括弧等在哪里;3栈中还有左括弧没有等到和它相匹配的右括弧。(自练习写算法)3.2.3 迷宫求解问题 计算机解迷宫时,通常用的是穷举求解穷举求解的方法 什么是迷宫问题?先看两个动画演示的例子(flash3-3-1;3-3-2)问题分析:1从入口进入迷宫之后,不管在迷宫的哪一个位置上,都是先往东走,如果走得通就继续往东走,如果在某个位置上往东走不通的话,就依次试探往南、往西和往北方向,从一个走得通的方向继续往前直到出口为止;2如果在某个位置上四个方向都走不通的话,就退回到前一个位置,换一个方向再试,如果
18、这个位置已经没有方向可试了就再退一步,如果所有已经走过的位置的四个方向都试探过了,一直退到起始点都没有走通,那就说明这个迷宫根本不通;3所谓走不通不单是指遇到墙挡路,还有已经走过的路不能重复走第二次,它包括曾经走过而没有走通的路。显然为了保证在任何位置上都能沿原路退回,需要用需要用一个一个“后进先出后进先出”的结构即栈来保存从入口到当前位置的的结构即栈来保存从入口到当前位置的路径路径。并且在走出出口之后,栈中保存的正是一条从入口到出口的路径。求迷宫中一条路径的算法的基本思想基本思想是:若若当前位置当前位置“可通可通”,则则纳入纳入“当前路径当前路径”,并继续朝,并继续朝“下一位置下一位置”探索
19、;探索;若若当前位置当前位置“不可通不可通”,则则应顺着应顺着“来的方向来的方向”退回到退回到“前一通道块前一通道块”,然后朝然后朝 着除着除“来向来向”之外的其他方向继续探索;之外的其他方向继续探索;若若该通道块的四周四个方块均该通道块的四周四个方块均“不可通不可通”,则则应从应从当前路径当前路径上删除该通道块。上删除该通道块。假设以栈栈S记录记录“当前路径当前路径”,则栈顶栈顶中存放的是存放的是“当当前路径上前路径上最后一个最后一个通道块通道块”。“纳入路径纳入路径”的操作即为的操作即为“当前位置入栈当前位置入栈”;从当前路径上删除前一通道块从当前路径上删除前一通道块的操作即为的操作即为出
20、栈出栈。求迷宫中一条从入口到出口的路径的伪码算法如下:设定当前位置的初值为入口位置;do 若若当前位置可通,则则将当前位置插入栈顶;/纳入路径 若若该位置是出口位置,则则算法结束;/此时栈中存放的是一条从入口位置到出口位置的路径否则否则切换当前位置的东邻方块为新的当前位置;否则否则 若若栈不空且栈顶位置尚有其他方向未被探索,则则设定新的当前位置为:沿顺时针方向旋转找到的栈顶位置的下一相邻块;若若栈不空但栈顶位置的四周均不可通,则则 删去栈顶位置;/从路径中删去该通道块若若栈不空,则则重新测试新的栈顶位置,直至直至找到一个可通的相邻块或出栈至栈空;while(栈不空栈不空);3.2.4 表达式求
21、值问题表达式求值问题 任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(delimiter)组成。其中 操作数:常数、标识符 运算符:算术运算符、关系运算符和逻辑运算符 基本界限符:左右括弧、表达式结束符等 以简单的二元运算符的算术表达式 二元表达式:操作数1(S1)操作符(OP)操作数2(S2)其中:操作数可以是简单变量,也可以是表达式;而简单变量可以是标识符,也可以是无符号整数。问题分析:由于算术运算的规则是:先乘除后加减、先左后右和先括弧内后括弧外,不按其中运算符出现的先后次序。那么怎么办?其中一个方法是先将它转换成另一种形式。在计算机中,对这种二元表达式
22、可以有三种不同的标识方法。假设 Exp=S1+OP+S2则称 OP+S1+S2 为表达式的前缀表示法前缀表示法(简称前缀式前缀式)称 S1+OP+S2 为表达式的中缀表示法中缀表示法(简称中缀式中缀式)称 S1+S2+OP 为表达式的后缀表示法后缀表示法(简称后缀式后缀式)例如:若 则它的前缀式为:中缀式为:后缀式为:综合比较它们之间的关系可得下列结论:1三式中的“操作数操作数之间的相对次序相同之间的相对次序相同”;2三式中的“运算符运算符之间的的相对次序不同之间的的相对次序不同”;3中缀式丢失了括弧信息,致使运算的次序不确定;4前缀前缀式的运算规则式的运算规则为:连续出现的两个操作数和在连续
展开阅读全文