CH3栈和队列.ppt
《CH3栈和队列.ppt》由会员分享,可在线阅读,更多相关《CH3栈和队列.ppt(97页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、通常称,栈和队列是限定插入和删除插入和删除只能只能在表的“端点端点”进行的线性表。线性表线性表 栈栈 队列队列Insert(L,i,x)Insert(S,n+1,x)Insert(Q,n+1,x)1in+1 Delete(L,i,&e)Delete(S,n,&e)Delete(Q,1,&e)1in栈和队列是两种常用的数据类型栈和队列是两种常用的数据类型3.1 栈的类型定义栈的类型定义3.2 栈的应用举例栈的应用举例3.3 栈类型的实现栈类型的实现3.4 队列的类型定义队列的类型定义3.5 队列类型的实现队列类型的实现一、栈的概念 栈栈(stackstack)是是插入插入和和删除删除操作限定在操
2、作限定在表尾表尾进进行的行的线性表线性表。栈的逻辑表示为:栈的逻辑表示为:S=S=(a a1 1,a,a2 2,a,an n)表尾元素表尾元素a an n称为称为栈顶栈顶(top)(top)表头元素表头元素a a1 1称为称为栈底栈底(bottom)(bottom)不含元素的空表称为不含元素的空表称为空栈空栈栈的概念栈的概念栈是限定在表的同一端进行插入或删除操作的线性表。进行插入或删除操作的一端称为栈顶,另一端称为栈底。栈的运算特性是栈的运算特性是后进先出后进先出(Last In Last In First Out-First Out-LIFOLIFO)或或先先进进后后出出(First Fir
3、st In Last Out-In Last Out-FILOFILO)k0k1.Kn-1栈顶栈底进栈出栈栈3.1 栈的类型定义栈的类型定义 ADT Stack 数据对象数据对象:D ai|ai ElemSet,i=1,2,.,n,n0 数据关系数据关系:R1|ai-1,aiD,i=2,.,n 约定an 端为栈顶,a1 端为栈底。基本操作:基本操作:ADT StackInitStack(&S)DestroyStack(&S)ClearStack(&S)StackEmpty(s)StackLength(S)GetTop(S,&e)Push(&S,e)Pop(&S,&e)StackTravers(
4、S,visit()InitStack(&S)操作结果:构造一个空栈 S。DestroyStack(&S)初始条件:栈 S 已存在。操作结果:栈 S 被销毁。StackEmpty(S)初始条件:栈 S 已存在。操作结果:若栈 S 为空栈,则返回 TRUE,否则 FALE。StackLength(S)初始条件:栈 S 已存在。操作结果:返回 S 的元素个数,即栈的长度。GetTop(S,&e)初始条件:栈 S 已存在且非空。操作结果:用 e 返回 S 的栈顶元素。a1a2an ClearStack(&S)初始条件:栈 S 已存在。操作结果:将 S 清为空栈。Push(&S,e)初始条件:栈 S 已
5、存在。操作结果:插入元素 e 为新的栈顶元素。a1a2ane Pop(&S,&e)初始条件:栈 S 已存在且非空。操作结果:删除 S 的栈顶元素,并用 e 返回其值。a1a2anan-1 3.2栈的表示和实现栈的表示和实现顺序栈顺序栈链栈链栈/-栈的顺序存储表示栈的顺序存储表示-#define STACK_INIT_SIZE 100;#define STACKINCREMENT 10;typedef struct SElemType *base;SElemType *top;int stacksize;SqStack;类似于线性表的顺序映象实现,指向表尾的指针可以作为栈顶指针。顺序栈示意图顺序
6、栈示意图*base*topstacksize.a1.aian*base*topstacksize初始初始空空栈栈*top=*base;stacksize=STACK_INIT_SIZE顺序栈顺序栈 Status InitStack(SqStack&S)/构造一个空栈S S.base=(ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType);if(!S.base)exit(OVERFLOW);/存储分配失败 S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;顺顺 序序 栈栈 的的 操操 作作 实实 现
7、现(GetTop)栈 S非 空,则 用 e返 回 栈 S中 栈 顶 元 素 的 值,并返回OK,则返回ERROR。Status GetTop(SqStack s,SElemType&e)ifif(s.top=s.base)returnreturn ERROR;e=*(s.top-1);return OK;/*GetTop */*base*topstacksize.a1.aianse*e=*(s.top-1);Status Pop(SqStack&S,SElemType&e)/若栈不空,则删除S的栈顶元素,/用e返回其值,并返回OK;/否则返回ERROR if(S.top=S.base)retu
8、rn ERROR;e=*-S.top;/-S.top;e=*S.top;return OK;*base*topstacksize.a1.aiansee=*(-s-top);e=*(-s-top);Status Push(SqStack&S,SElemType e)if(S.top-S.base=S.stacksize)/栈满,追加存储空间 S.base=(ElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType);if(!S.base)exit(OVERFLOW);/存储分配失败 S.top=S.base+S.s
9、tacksize;S.stacksize+=STACKINCREMENT;*S.top+=e;/*S.top=e;S.top+;return OK;插入新的栈顶元素时,堆栈变化示意e*base*topstacksize.a1.aians*base*topstacksize.a1.aians栈满时,追加存储空间栈满时,追加存储空间*(s-top+)=e;*(s-top+)=e;e思考题:思考题:一个栈的入栈序列为:一个栈的入栈序列为:1 2 3,那么可能得到的出栈序,那么可能得到的出栈序列是什么?列是什么?2.设将整数设将整数1,2,3,4依次进栈,但只要出栈时栈非空,依次进栈,但只要出栈时栈非
10、空,则可将出栈操作按任何次序夹入其中,请回答下述问则可将出栈操作按任何次序夹入其中,请回答下述问题:题:(1)若入、出栈次序为若入、出栈次序为Push(1),Pop(),Push(2),Push(3),Pop(),Pop(),Push(4),Pop(),则出栈的数字序列为何?则出栈的数字序列为何?(2)能否得到出栈序列能否得到出栈序列1423和和1432?并说明为什么不能得到或并说明为什么不能得到或者如何得到。者如何得到。(3)请分析请分析 1,2,3,4 的的24种排列中,哪些序列是可以通种排列中,哪些序列是可以通过相应的入出栈操作得到的。过相应的入出栈操作得到的。答:答:3 2 1,2 3
11、 1,2 1 3,1 3 2,1 2 3。不能不能 有有 312 仅当两个栈顶相遇时,才产生上溢,即所有可用空间仅当两个栈顶相遇时,才产生上溢,即所有可用空间已用完。对每个栈可用的最大空间就可能大于整个可用已用完。对每个栈可用的最大空间就可能大于整个可用空间的一半空间的一半m/2。栈1栈2空闲栈bot1top1bot2top21m2.栈的系统存储空间共享。(两栈共享)栈的系统存储空间共享。(两栈共享)3.1.4 链栈的表示和实现1.栈的链式存储表示栈的链式存储表示typedef struct SNode ElemType data;struct SNode*next;SNode,*LinkSt
12、ack;问:问:链栈中为何不设置头结点链栈中为何不设置头结点?答:链栈不需要在头部附加头结点,因答:链栈不需要在头部附加头结点,因为栈都是在头部进行操作的,如果加了为栈都是在头部进行操作的,如果加了头结点,等于要对头结点之后的结点进头结点,等于要对头结点之后的结点进行操作,反而使算法更复杂,所以只要行操作,反而使算法更复杂,所以只要有链表的首指针就可以了。有链表的首指针就可以了。anan-1ai+1aia1栈顶栈顶栈底栈底3.链栈基本操作的实现链栈基本操作的实现初始化初始化S=NULL;入栈入栈申请结点申请结点p;p-data=e;p-next=S;S=p;判空:判空:S=NULL出栈:出栈:
13、if(S=NULL)return ERROR;else p=S;S=p-next;e=p-data;free(p);anan-1ai+1aia1栈顶栈顶栈底栈底练习(1)栈是限定在_处进行插入或删除操作的线性表。A.端点 B.栈底 C.栈顶 D.中间(2)4个元素按A、B、C、D顺序连续进S栈,进行Pop(S,x)运算后,x的值是_。A.A B.B C.C D.D(3)栈的特点是_。A.先进先出 B.后进先出 C.后进后出 D.不进不出(4)栈与一般线性表的区别主要在_方面。A.元素个数 B.元素类型C.逻辑结构 D.插入、删除元素的位置(5)一个栈的输入序列为1,2,3,4,5,则下列序列中
14、不可能是栈的输出序列的是_。A.2,3,4,1,5,B.5,4,1,3,2,C.2,3,1,4,5,D.1,5,4,3,2B3.3 栈的应用举例栈的应用举例例一、例一、数制转换数制转换例二、例二、括号匹配问题括号匹配问题例三例三 表达式求值表达式求值 例一、例一、数制转换数制转换 算法基于原理:N=(N div d)d+N mod d 例如:例如:(1348)10=(2504)8,其运算过程如下:N N div 8 N mod 81348 168 4 168 21 0 21 2 5 2 0 2计计算算顺顺序序输输出出顺顺序序*base*topstacksize4052先进后出:先进后出:数据生
15、成的顺序:数据生成的顺序:4,0,5,24,0,5,2 读出的顺序:读出的顺序:2,5,0,42,5,0,4void conversion()InitStack(S);scanf(%d,N);while(N)Push(S,N%8);N=N/8;while(!StackEmpty(S)Pop(S,e);printf(%d,e);/conversion例2:括号匹配的检查例如:例如:()()()()()()()算法的设计思想:算法的设计思想:1)凡出现左括弧,则进栈;)凡出现左括弧,则进栈;2)凡出现右括弧,首先检查栈是否空)凡出现右括弧,首先检查栈是否空若栈空,则表明该若栈空,则表明该“右括弧右
16、括弧”多余多余否则和栈顶元素比较,否则和栈顶元素比较,若相匹配,则若相匹配,则“左括弧出栈左括弧出栈”否则表明不匹配否则表明不匹配3)表达式检验结束时,)表达式检验结束时,若栈空,则表明表达式中匹配正确若栈空,则表明表达式中匹配正确否则表明否则表明“左括弧左括弧”有余有余Status Compare()InitStack(S);flag=TURE;while(ch=getchar())!)!=#)&flag)switch(ch)case(:case :caxe :Push(S,ch);break;case):if(Pop(S,e)=ERROR|e!=()flag=FALSE;break;cas
17、e :if(Pop(S,e)=ERROR|e!=)flag=FALSE;break;case :if(Pop(S,e)=ERROR|e!=)flag=FALSE;break;/switch if(flag&ch=#&StackEmpty(S)return TRUE;else return FALSE;例例3 3:栈的应用栈的应用-表达式求值表达式求值一一.表达式表达式 表达式表达式由操作数、运算符和界限符组成。由操作数、运算符和界限符组成。操作数操作数(operand):常数或变量常数或变量运算符运算符(operator)算术运算符:算术运算符:+、-、*、/、*等等关系运算符:、关系运算符:
18、、逻辑运算符:逻辑运算符:AND、OR、NOT界界限限符符(delimiter):左左右右括括号号、表表达达式式结结束束符符等等例例3 3:栈的应用:栈的应用-表达式求值表达式求值二二.算符优先关系表算符优先关系表 先乘除,后加减:先乘除,后加减:*、/+、先括号内,后括号外:先括号内,后括号外:同级按左结合律:同级按左结合律:以下为不允许的:以下为不允许的:)与(、(与、与)与(、(与、与)+-*/()#+-*/()#=12三.算术表达式求值的算符优先算法使用使用DS算符栈算符栈OPTR:有效算符;有效算符;操作数栈操作数栈OPND:有效操作数,运算结果。有效操作数,运算结果。算法思想算法思
19、想(1)初始化:)初始化:OPND置为空栈,将放入置为空栈,将放入OPTR栈底栈底(2)依次读入表达式中的每个字符,)依次读入表达式中的每个字符,若是操作数,则入若是操作数,则入OPND栈;栈;若是算符,则和若是算符,则和OPTR栈顶算符进行优先级比较:栈顶算符进行优先级比较:若栈顶算符优先,则执行相应运算,结果存入若栈顶算符优先,则执行相应运算,结果存入OPND栈栈 若与栈顶算符相等,则作()或处理。若与栈顶算符相等,则作()或处理。若栈顶算符低于,该算符入若栈顶算符低于,该算符入OPTR栈。栈。(3)重复(重复(2),直到表达式求值完毕),直到表达式求值完毕 (读入的是(读入的是#,且,且
20、OPTR栈顶元素也为栈顶元素也为#)3算法描述算法描述OperandType Evaluateexpress()InitStack(OPTR);Push(OPTR,#);InitStack(OPND);c=getchar();while(c!=#|GetTop(OPTR)!=#)if(c为操作数)为操作数)Push(OPND,c);c=getchar();/不是运算符不是运算符进栈进栈 else switch Precede(GetTop(OPTR),c)case:/退栈并将运算结果入栈退栈并将运算结果入栈 Pop(OPTR,thrta);Pop(OPND,b);Pop(OPND,a);Pus
21、h(OPND,Operate(a,theta,b);break;/switch/Evaluateexpress输入:3*(7+3*6/2-5#)运算对象栈运算符栈3#*(7+3*618/2916-51133有关思考与提示有关思考与提示算符优先表的存储和表示算符优先表的存储和表示;栈的选择(静态顺序栈栈的选择(静态顺序栈-用数组表示)用数组表示)判断判断c是否为算符。是否为算符。Operate(a,theta,b)的实现的实现3.3 栈与递归的实现一、函数调用与返回通常,当一个函数调用另一个函数时,在执行被调用函数前系统要预先做三件事情:将所有的实参和函数返回地址等信息传递给被调用函数;为被调用
22、函数的局部变量分配存储空间将控制转移到被调用函数的入口处。而而在在从从被被调调用用函函数数返返回回调调用用函函数数之之前前,系系统统也需要做如下三件事情:也需要做如下三件事情:保存被调用函数的计算结果;保存被调用函数的计算结果;释释放放为为被被调调用用函函数数局局部部变变量量分分配配的的数数据据空空间;间;按返回地址将控制转移给调用函数。按返回地址将控制转移给调用函数。二、函数的嵌套调用当多个函数构成嵌套调用时,系统按照先调用后返回的原则进行工作。这种信息的传递和控制转移符合后进先出的原则,使用栈来实现是非常自然的。例:设有一个主程序,它调用函数a,函数a又调用函数b,函数b又调用函数c,(见
23、下页),其中r,s,t分别表示中断地址,我们可以用一个栈来描述调用情况(见下页)r主主程程序序srrrs函函数数1rst函函数数2rst函函数数3多个函数嵌套调用的规则是:此时的内存管理实行“栈式管理栈式管理”后调用先返回后调用先返回!例如:void main()void a()void b()a();b();/main /a /bMain的数据区函数a的数据区函数b的数据区 注:系统将整个程序运行期间所需要的存储空间都利用一个工作栈来管理,每当调用(或执行)一个函数时,就为它在栈顶分配一个存储区;每当退出(或执行完)一个函数时,就释放为它所分配的存储区;当前工作的函数的数据区总在工作栈的当前
24、栈顶位置。三、递归函数的执行过程递归函数的执行过程类似于嵌套调用时的情况,只不过是在直接递归时的调用函数和被调用函数是同一个函数罢了递归是程序设计中一个强有力的工具,可以解决许多实际应用问题:递归定义的数学函数递归的数据结构问题的定义是递归的 递归问题递归问题例:例:Hanoi塔问题塔问题分析:分析:n n个个 X Y Z (1)(1)将将X X轴上的轴上的n-1n-1个盘子借助个盘子借助Z Z轴移到轴移到Y Y轴上;轴上;(2)(2)将将X X轴上的余下的轴上的余下的1 1个盘子移到个盘子移到Z Z轴上;轴上;(3)(3)将将Y Y轴上的轴上的n-1n-1个盘子借助个盘子借助X X轴移到轴移
25、到Z Z轴上轴上求解算法及调用示意图求解算法及调用示意图void void hanoi(inthanoi(int n,char n,char x,char y,char z)x,char y,char z)if(n=1)move(x,1,z);if(n=1)move(x,1,z);else hanoi(n-else hanoi(n-1,x,z,y);1,x,z,y);move(x,n,z);move(x,n,z);hanoi(n-hanoi(n-1,y,x,z);1,y,x,z);Hanoi(3,a,b,c)Hanoi(3,a,b,c)Hanoi(1,a,b,c)Hanoi(1,b,c,a)H
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CH3 队列
限制150内