数据结构严蔚敏C语言版第三章课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《数据结构严蔚敏C语言版第三章课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 严蔚敏 语言版 第三 课件
- 资源描述:
-
1、3.1.1 3.1.1 栈的定义及基本运算栈的定义及基本运算 3.1 3.1 栈栈( (Stack)Stack)假设栈假设栈S=(aS=(a1 1,a a2 2,a a3 3,a an n) ),则,则a a1 1称为栈底元素称为栈底元素,a an n为栈为栈顶元素顶元素。栈中元素按。栈中元素按a a1 1,a a2 2,a a3 3,a an n的次序进栈,退栈的的次序进栈,退栈的第一个元素应为栈顶元素。换句话说,栈的修改是按后进第一个元素应为栈顶元素。换句话说,栈的修改是按后进先出的原则进行的。因此,栈又称为先出的原则进行的。因此,栈又称为后进先出后进先出 ( (LIFO)LIFO)表表。
2、栈是限制在表的一端进行插入和删除运算的线性表,通栈是限制在表的一端进行插入和删除运算的线性表,通常称插入、删除的这一端为常称插入、删除的这一端为栈顶栈顶( (Top)Top),另一端为,另一端为栈底栈底( (Bottom)Bottom)。当栈中没有元素时称为空栈。当栈中没有元素时称为空栈。例、一叠书或一叠盘子。例、一叠书或一叠盘子。 a n a n-1 a2 a1栈顶 栈底抽象数据类型抽象数据类型栈栈ADT Stack 数据对象数据对象: D=a ai i |a|ai i ElemSet, i=1,2,ElemSet, i=1,2,n (n=0),n (n=0) 数据关系:数据关系:R=aR=
3、| a| ai-1i-1,a,ai i D,i=2,3,D,i=2,3,n,n 约定约定a an n端为栈顶,端为栈顶,a a1 1端为栈底。端为栈底。 基本操作基本操作: InitStack(&S)InitStack(&S) 操作结果操作结果: 建立一个空栈建立一个空栈S DestroyStack(&S)DestroyStack(&S) 初始条件:初始条件:栈栈S已存在已存在 操作结果操作结果: 栈栈S被销毁被销毁 ClearStack(&S)ClearStack(&S) 初始条件:初始条件:栈栈S已存在已存在 操作结果操作结果: 将将S栈清空栈清空StackEmpty(S)StackEmp
4、ty(S) 初始条件初始条件:栈栈S已存在已存在 操作结果操作结果:若栈:若栈S为空栈,返回为空栈,返回true,否则返回否则返回falseStackLength(S)StackLength(S) 初始条件初始条件:栈栈S已存在已存在 操作结果操作结果: 返回返回S的元素个数的元素个数GetTop(S,&e) /读栈顶元素读栈顶元素 初始条件初始条件:栈栈S已存在且非空已存在且非空 操作结果操作结果: 用用e返回栈顶元素返回栈顶元素Push(Push(&S,e) /入栈入栈 初始条件初始条件:栈栈S已存在已存在 操作结果操作结果: 将将元素元素e插入到栈顶插入到栈顶Pop(&S,&e) /出栈
5、出栈 初始条件初始条件:栈栈S已存在且非空已存在且非空 操作结果操作结果: 删除删除S的栈顶元素,用的栈顶元素,用e返回返回StackTraverse(S,visit() 初始条件初始条件:栈栈S已存在且非空已存在且非空 操作结果操作结果: 从栈底到栈顶依次对从栈底到栈顶依次对S的每个元素调用的每个元素调用visit()ADT Stack 由于栈的逻辑结构与线性表相同,因此线性表由于栈的逻辑结构与线性表相同,因此线性表的存储结构对栈也适应。的存储结构对栈也适应。3.1.2 3.1.2 栈的表示和实现栈的表示和实现v 顺序栈顺序栈v 链栈链栈栈的顺序存储结构简称为顺序栈,由于栈底位置栈的顺序存储
6、结构简称为顺序栈,由于栈底位置是固定不变的,所以可以将栈底位置设置在数组是固定不变的,所以可以将栈底位置设置在数组两端的任何一端;两端的任何一端;而栈顶位置是随着入栈和出栈而栈顶位置是随着入栈和出栈操作而变化的操作而变化的. .v顺序栈顺序栈顺序栈的类型定义如下:顺序栈的类型定义如下: #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef struct SElemType *base; /栈底指针,栈底指针,base=NULL表明栈不存在表明栈不存在 SElemType *top; /栈顶指针栈顶指针,top=base为栈空
7、的标志为栈空的标志 int stacksize; /栈当前可以使用的最大容量栈当前可以使用的最大容量 SqStack; 栈顶指针栈顶指针top,指向栈底指向栈底位置位置top入栈入栈Atop出栈出栈栈满栈满BCDEF设数组大小为设数组大小为stacksizetop=base,栈空,此时出栈,则栈空,此时出栈,则下溢下溢(underflow)top= stacksize,栈满,此时入栈,则栈满,此时入栈,则上溢上溢(overflow)toptoptoptoptoptoptoptoptoptoptop栈空栈空top123450栈空栈空base123450ABCDEFbase123450base顺序
8、栈的入栈与出栈顺序栈的入栈与出栈0M-1栈栈1底底栈栈1顶顶栈栈2底底栈栈2顶顶在一个程序中同时使用两个栈在一个程序中同时使用两个栈1、构造一个空栈、构造一个空栈 Status InitSatck(SqStack &S) S.base=(SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType); if(!S.base) exit(OVERFLOW); S.top=S.base; S.stacksize= STACK_INIT_SIZE; /end InitSatck 基本操作的算法描述基本操作的算法描述2、返回栈顶元素、返回栈顶元素 Status
9、 GetTop(SqStack S,SElemTtype &e) if (S.top=S.base) return ERROR; e=*(S.top-1); return OK; /end GetTop 3 3、入栈、入栈Status Push(SqStack &S,SElemType e) if(S.top-S.base=S.stacksize) S.base=(SElemType*)realloc(S.base,(S. stacksize + STACKINCREMENT)* sizeof(SElemType); if(!S.base) exit(OVERFLOW); S.top=S.ba
10、se+S.stacksize; S.stacksize+= STACKINCREMENT; *S.top+=e;/end Push4 4、出栈、出栈 Status Pop(SqStack &S,SElemType &e) if(S.top=S.base) return ERROR; e=*-S.top; return OK;/end Pop 栈顶栈顶.topdata next栈底栈底v链栈链栈其操作与线性链表类似其操作与线性链表类似 3.2.1 3.2.1 数制转换数制转换 3.2.2 3.2.2 括号匹配的检验括号匹配的检验 3.2.3 3.2.3 行编辑程序行编辑程序 3.2.5 3.2.
11、5 表达式求值表达式求值3.2 栈的应用举例栈的应用举例十进制十进制n n和其它进制数和其它进制数d d的转换是计算机实现计算的的转换是计算机实现计算的基本问题基本问题, ,其解决方法很多其解决方法很多, ,其中一个简单算法基于其中一个简单算法基于下列原理下列原理: : n=(n div d)n=(n div d)* *d + n mod dd + n mod d ( ( 其中其中: :divdiv为整除运算为整除运算, ,modmod为求余运算为求余运算) ) 例如例如 ( (1348)1348)1010=(2504)=(2504)8 8,其运算过程如下:其运算过程如下:3.2.1 数制转换
12、数制转换 例如:例如:(1348)10 = (2504)8 , 其运算过程如下:其运算过程如下: 计算顺序计算顺序输出顺序输出顺序 n n div 8 n mod 8 1348 168 4 168 21 0 21 2 5 2 0 2算法算法3.1 void conversion( ) /十进制转换为等值的八进制十进制转换为等值的八进制 Initstack(S); scanf (“%d”,N); while(N) Push(S,N%8); N=N/8; while(! StackEmpty(S) Pop(S,e); printf(“%d”,e); /end conversion假设表达式中充许括
13、号嵌套假设表达式中充许括号嵌套, ,则检验括号是否匹配的方法则检验括号是否匹配的方法可用可用“期待的急迫程度期待的急迫程度”这个概念来描述。例:这个概念来描述。例: ( ) ( ) 1 2 3 4 5 6 7 83.2.2 括号匹配的检验括号匹配的检验分析出现的分析出现的不匹配不匹配的情况的情况:到来的右括号到来的右括号不是所不是所“期待期待”的的;1)凡出现凡出现左括号,则入栈;左括号,则入栈;2)凡出现凡出现右括号,右括号,首先检查首先检查栈是否空栈是否空. . 若若栈空,栈空,则表明该则表明该“右括号右括号”多余多余, , 否则否则和栈顶元素和栈顶元素比较比较, 若若相匹配,相匹配,则则
14、“左括号出栈左括号出栈”, ,否则表明否则表明括号不匹括号不匹配配. .3)表达式检验结束时,表达式检验结束时, 若若栈空栈空,则表明表达式中,则表明表达式中括号匹配括号匹配, , 否则表明否则表明“左括号左括号”有余有余算法的设计思想:算法的设计思想:Status matching(string &exp) int state = 1; InitStack(S);while (i=StrLength(exp) & state) switch of expi case “(” : Push(S,expi); i+; break; case “)”: if(!StackEmpty(S) & Ge
15、tTop(S)=“(”) Pop(S,e); i+; else state = 0; break; if (StackEmpty(S) & state) return OK;检验括号匹配的算法:检验括号匹配的算法:在用户输入程序或数据时,允许用户输入出差错,当发现在用户输入程序或数据时,允许用户输入出差错,当发现有误时,可以及时更正。方法是:有误时,可以及时更正。方法是:设立一个输入缓冲区,用于接受用户输入的一行字符,然设立一个输入缓冲区,用于接受用户输入的一行字符,然后逐行存入用户数据区。后逐行存入用户数据区。假设退格符假设退格符“#”“#”表示前一个字符无效;表示前一个字符无效;退行符退行
16、符“”“”表示当前行中的字符全无效。表示当前行中的字符全无效。3.2.3 行编辑程序行编辑程序假设从终端接受了这样两行字符假设从终端接受了这样两行字符 whli#ilr#e(s#*s) outchaputchar(*s=#+);则实际有效的是下列两行:则实际有效的是下列两行: while (*s) putchar(*s+);void LineEdit( ) InitStack(S); /栈栈S设为输入缓冲区设为输入缓冲区 ch=getchar( ); while(ch!=eof) while(ch!=eof & ch!=n) switch(ch) case # : Pop(S,ch); /书上
17、为书上为c case : ClearStack(S); default : Push(S,ch); /end switch ch=getchar( ); /end while将从栈底到栈顶内的字符传送到用户数据区;将从栈底到栈顶内的字符传送到用户数据区; ClearStack(s); if(ch!=eof) ch=gethar( ); /end whileDestroyStack(s);/end LineEdit行编辑程序算法:行编辑程序算法: 3.2.5 表达式求值表达式求值例如:例如:3*(7 2 ) (1)算术四则运算的规则:)算术四则运算的规则: a. 从左算到右从左算到右 b. 先乘
18、除,后加减先乘除,后加减 c. 先括号内,后括号外先括号内,后括号外 由此,此表达式的计算顺序为:由此,此表达式的计算顺序为: 3*(7 2 )= 3 * 5 = 15(2)根据上述三条运算规则,在运算的每一步中,对)根据上述三条运算规则,在运算的每一步中,对任意相继出现的算符任意相继出现的算符 1和和 2 ,都要比较优先权关系。,都要比较优先权关系。算符优先法所依据的算符间的优先关系算符优先法所依据的算符间的优先关系见教材见教材P53表表3.1由表可看出,右括号由表可看出,右括号 ) 和井号和井号 # 作为作为 2时时级别最低;级别最低; 由由c规则规则得出:得出: * ,/, + ,-为为
19、 1时的优先权低于时的优先权低于(,高于,高于) 由由a规则规则得出:得出:(=) 表明括号内运算,已算完。表明括号内运算,已算完。 # = # 表明表达式求值完毕。表明表达式求值完毕。令令OP=+,-,*,/,(,),(,),# 3.2.5 表达式求值表达式求值(3)算法思想:)算法思想:设两个栈:操作符栈设两个栈:操作符栈 OPTR ,操作数栈,操作数栈 OPND栈初始化:设操作数栈栈初始化:设操作数栈 OPND 为空;操作符栈为空;操作符栈 OPTR 的栈底的栈底 元素为表达式起始符元素为表达式起始符 #;依次读入字符:是操作数则入依次读入字符:是操作数则入OPND栈,是操作符则要判断:
20、栈,是操作符则要判断: if 操作符操作符( 1) 栈顶元素,压入栈顶元素,压入OPTR栈。栈。 3.2.5 表达式求值表达式求值OPTROPNDINPUTOPERATE3*(7-2)#Push(opnd,3) #*(7-2)#3#Push(optr,*)#, *3(7-2)#Push(optr,()#, *, (37-2)#Push(opnd,7)#, *, (3,7-2)#Push(optr,-)#, *, (, 3,72)#Push(opnd,2)#, *, (, 3,7,2)#Operate(7-2)#, *, (3,5)#Pop(optr)#, *3,5#Operate(3*5)#1
21、5#GetTop(opnd) 例例 求表达式求表达式3*(7-2)Status EvaluateExpression( OperandType &result) InitStack(OPND); InitStack(OPTR); Push(OPTR ,#); c=getchar( ); while(c!=#)&(GetTop(OPTR)!=#) if (!In(c,OP) Push(OPND,c); c=getchar( ); else switch(compare(c,GetTop(OPTR) case : Push(OPTR , c); c=getchar( ); break; case
22、=: Pop(OPTR,x); c=getchar( ); break; case : Pop(OPTR,tem); Pop(OPND,b ); a=Pop(OPND,a ); c=getchar( ); break; /switch /while result=GetTop(OPND);/End EvaluateExpression3.2.4 迷宫求解迷宫求解 入口入口出口求迷宫路径算法的基本思想是:求迷宫路径算法的基本思想是:v若当前位置若当前位置“可通可通”,则纳入路径,继续前进,则纳入路径,继续前进; 若当前位置若当前位置“不可通不可通”,则后退,换方向继续,则后退,换方向继续探索探索
23、; 若四周若四周“均无通路均无通路”,则将当前位置从路径中,则将当前位置从路径中删除出去。删除出去。设当前位置为入口位置设当前位置为入口位置do if(当前位置可通当前位置可通) 当前位置插入栈顶当前位置插入栈顶; if(该位置是出口位置该位置是出口位置) 结束结束 else 切换当前位置的东邻方块为新的当前位置切换当前位置的东邻方块为新的当前位置; else if(栈不空栈顶位置尚有其它方向未经探索栈不空栈顶位置尚有其它方向未经探索) 设定新的当前位置为顺时针方向旋转找到的顶点设定新的当前位置为顺时针方向旋转找到的顶点 位置的下一个邻块位置的下一个邻块; if(栈不空且栈顶位置的四周均不通栈
24、不空且栈顶位置的四周均不通) 删去栈顶元素位置删去栈顶元素位置,直至找到一个可通的相邻块或直至找到一个可通的相邻块或 出栈或栈空出栈或栈空; while(栈不空栈不空);求迷宫中一条从入口到出口的路径的算法思想:求迷宫中一条从入口到出口的路径的算法思想:Type struct int ord; /通道块在路径上的序号通道块在路径上的序号 PosType seat; /通道块在迷宫中的通道块在迷宫中的“坐标位置坐标位置” int di; /从此通道块走向下一通道块的方向从此通道块走向下一通道块的方向SElemType; /栈元素类型栈元素类型Status MazePath(MazeType ma
展开阅读全文