_第4章_栈和队列.pptx
- 文档编号:1080726
- 上传时间:2022-10-16
- 格式:PPTX
- 页数:89
- 大小:849.58KB
_第4章_栈和队列.pptx
《_第4章_栈和队列.pptx》由会员分享,可在线阅读,更多相关《_第4章_栈和队列.pptx(89页珍藏版)》请在冰豆网上搜索。
,主要内容栈栈的应用举例队列队列的应用举例,*,Tuesday,October20,2009,栈和队列是软件设计中最常用的两种数据结构,它们的逻辑结构与线性表相同,其特点是运算受到限制:
栈按“后进先出”的规则进行操作,队列按“先进先出”的规则进行操作,故称它们是运算受限制的线性表。
4.1栈4.1.1栈的结构特点和操作1.定义栈是限定仅在表的一端(表尾)进行插入和删除操作的线性表。
栈中允许插入和删除的一端叫栈顶top,表尾称为栈顶;栈中不允许插入和删除的一端叫栈底bottom,表头称为栈底;不含数据元素的空表称为空栈。
*,Tuesday,October20,2009,栈的插入操作称为进栈或入栈,栈的删除操作称为出栈或退栈。
每次入栈的元素总放在原栈顶元素之上成为新的栈顶,而每次出栈的元素总是当前栈中的最新的元素,也就是最后进栈的元素。
栈又称为先进后出或后进先出表。
(FILO或LIFO)。
2.栈的基本操作InitStack(&S)将S初始化为空栈DestroyStack(&S)将栈S销毁,*,Tuesday,October20,2009,3)ClearStack(&S)4)StackEmpty(S)5)StackFull(S)6)StackLength(S),将栈S置成空栈若栈S为空栈返回TRUE否则返回FALSE若栈S已满返回TRUE,否则返回FALSE栈S存在则返回S的元素个数,即栈的长度,7)GetTop(S,&e),栈S存在且非空则返回S的栈顶元素,栈S存在且不满则插入元素e为新的栈顶元素,9)Pop(&S,&e)栈S存在且非空则删除S的栈顶元素并用e返回其值,GetTop(S,&e)与Pop(&S,&e)不同在于GetTop(S,&e)不改变栈顶的位置。
an,a1a28)Push(&S,e)a1a2,ane,*,Tuesday,October20,2009,10)StackTraverse(S)栈S存在且非空则从栈底到栈顶依次输出栈S中的每个数据元素4.1.2栈的表示和实现栈的存储方式:
顺序栈和链栈1.顺序栈:
利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置。
通常用top=-1表示空栈。
/-顺序栈的存储表示-,a1a2,an-1an,*,Tuesday,October20,2009,constSTACK_INIT_SIZE=100;constSTACKINCREMENT=10;,*,Tuesday,October20,2009,typedefstructSElemType*elem;inttop;intstacksize;intincrement;SqStack;1).初始化栈voidInitStack(SqStack/InitStack,得到栈顶元素boolGetTop(SqStackS,SElemType/Pop,*,Tuesday,October20,2009,4).入栈一个元素voidPush(SqStack/Push,*,Tuesday,October20,2009,输出栈中的元素voidStackTraverse(SqStackS)for(inti=0;i=S.top;i+)coutS.elemi)“”;coutendl;栈中元素的个数intStackLength(SqStackS)return(S.top+1);判栈空boolStackEmpty(SqStackS)if(S.top=-1)returntrue;elsereturnfalse;,*,Tuesday,October20,2009,2.链栈若栈中元素的个数无法确定可以使用链栈(利用链式分配实现的栈),链栈中指针的方向是从栈顶指向栈底。
typedefstructLNodeSElemTypedata;structLNode*next;LNode,*LinkList;typedefLinkListLinkStack;LinkStackS;,ana1,an-1,栈顶指针S结构定义:
*,Tuesday,October20,2009,初始化栈voidInitStack(LinkStack/修改栈顶指针/Push,*,Tuesday,October20,2009,3).让栈顶元素出栈boolPop(LinkStack&S,SElemType&e)/若栈不空,则删除栈顶元素,以e返回其值,并返回true,否则返回falseif(S),*,Tuesday,October20,2009,S=S-next;deletep;,LNode*p=S;e=p-data;returntrue;,/ifelsereturnfalse;/Pop4).得到栈顶元素boolGetTop(LinkStack/GetTop,5).栈中元素的个数intStackLength(LinkStackS)intk=0;LNode*p=S;while(p),*,Tuesday,October20,2009,k+;,p=p-next;returnk;/StackLength6).判栈空,boolStackEmpty(LinkStackS)if(S)returnfalse;returntrue;/StackEmpty,4.2栈的应用举例,例4.1数制转换例4.2括号匹配的检验例4.3背包问题求解例4.4表达式求值例4.5实现递归例4.1数制转换问题:
输入一个非负十进制整数,打印输出与其等值的八进制数.例如:
(1348)10=(2504)8,其运算过程如下:
NNdiv8Nmod8计算,*,Tuesday,October20,2009,/首先应定义栈中数据元素的类型为int类型typedefintSElemType;/算法4.1voidconversion()SqStackS;intN;SElemTypee;InitStack(S);/构造空栈cinN;while(N)Push(S,N%8);/余数入栈N=N/8;/商继续运算while(!
StackEmpty(S)Pop(S,e);coute;/求余所得相逆的顺序输出八进制的各位数/conversion主程序为voidmain()conversion();,*,Tuesday,October20,2009,*,Tuesday,October20,2009,例4.2括号匹配:
检验表达式中所含括弧是否正确嵌套,若是,则返回TRUE,否则返回FALSE.#为表达式的结束符假设在表达式中允许包含两种括号:
()和,其嵌套顺序随意,即()或()等为正确的格式,()或()或())均为不正确的格式。
检验括号是否匹配的方法可用“等待的急迫程度”这个概念来描述。
例如:
考虑下列括号序列:
分析可能出现的不匹配的情况:
到来的右括弧并非是所“期待”的;到来的是“不速之客”;直到结束,也没有到来所“期待”的括弧。
算法的设计思想:
*,Tuesday,October20,2009,凡出现左括弧,则进栈凡出现右括弧,首先检查栈是否空;若栈空,则表明该“右括弧”多余,否则和栈顶元素比较,若相匹配,则“左括弧出栈”,否则表明不匹配。
表达式检验结束时,若栈空,则表明表达式中匹配正确,否则表明“左括弧”有余。
boolmatching(charexp)/算法4.2/检验表达式中所含括弧是否正确嵌套,若是,则返回true,/否则返回flase.#为表达式的结束符SqStackS;InitStack(S);,break;/左括弧入栈,*,Tuesday,October20,2009,intstate=1;chare;charch=*exp+;while(ch!
=#case):
if(!
StackEmpty(S),case:
*,Tuesday,October20,2009,if(!
StackEmpty(S)/while,if(state,*,Tuesday,October20,2009,例4.3背包问题:
假设有一个能装入总体积为T的背包和n件体积分别为w1,w2,w3,wn的物品,能否从n件物品中挑选若干件恰好装满背包,即使wi1+wi2+wik=T,要求找出所有满足上述条件的解。
例如,当T=10,各件体积为1,8,4,3,5,2时,可找到下列4组解:
(1,4,3,2),(1,4,5),(8,2)和(3,5,2)。
方法:
利用“回溯”的设计思想来解背包问题。
过程:
首先将物品排成一列,然后顺序选取物品装入背包,假设已选取了前i件物品之后背包还没有装满,则继续选取第i+1件物品,若该件物品“太大”不能装入,则弃置而继续选取下一件,直至背包装满为止。
*,Tuesday,October20,2009,但如果在剩余物品中找不到合适的物品以填满背包,则说明“刚刚”装入背包的那件物品“不合适”,应将它取出“弃置一边”,继续再从“它之后”的物品中选取,如此重复,直至求得满足要求的解,或者“无解”为止。
回溯:
从当前背包中取出物品再继续搜索的策略称之为“回溯”。
由于回溯求解的规则为“后进先出”(在此问题中物品取出的顺序恰好和装入的顺序相反),因此要用到栈。
具体做法:
对物品进行顺序编号(从0号起),然后从0号物品起顺序选取,若可以装入背包,则将该物品号“入栈”,背包体积减小,有两种情况:
若背包正好装满,则输出一组解(之后回溯找下一组解)若尚未求得解时已无物品可选,则从栈顶退出最近装入的物品号(假设为k),之后继续从第k+1件物品起挑选。
*,Tuesday,October20,2009,结束条件:
栈S空并且物品号k为最后一件物品求解过程中栈的状态变化:
依次将“0”和“1”入栈(表示将体积为1的0号物品和体积为8的1号物品装入背包),此时背包尚未装满,而其余编号为2,3,4,5的物品都因为体积“太大”而不能装入,则将栈顶的“1”退出(表示从背包中取出体积为8的1号物品),之后依次将“2”和“3”入栈(表示将体积为4的2号物品和体积为3的3号物品装入背包),此时因4号物品“太大”不能装入,则弃置一边,而装入5号物品,即“5”入栈,此时背包正好装满,至此求得一组解。
为了继续求其它解,令“5”出栈,因没有其他可选物品,则“3”(从栈顶退出最近装入的“3”)继续出栈,之后“4”继续入栈,Tu求es得da第y,O2c组to解ber。
20依,20次09类推,直nys至fxy求得126全.co部m解。
*,10,51背包问题求解过程中栈的状态变化情况算法4.3已知n件物品的体积分别为w0,w1,wn-1,背包的总体积为T,本算法输出所有恰好能装满背包的物品组合解。
42,3534,180215,*,Tuesday,October20,2009,voidknapsack(intw,intT,intn)SqStackS;intm=0;InitStack(S);intk=0;/从第0件物品考察起dowhile(T0/输出一组解,之后回溯寻找下一组解,*,Tuesday,October20,2009,Pop(S,k);k+;,T+=wk;/退出栈顶物品背包剩余体积增wk/继续考察下一件物品,while(!
StackEmpty(S)|k!
=n);,cout总共有m组装法endl;,*,Tuesday,October20,2009,/knapsackvoidmain()intw10;intt;coutt;coutwi;knapsack(w,t,10);/main,例4.4表达式求值任何一个表达式都是由操作数、运算符和界限符组成。
限于二元运算符的表达式定义:
表达式:
=(操作数)+(运算符)+(操作数)操作数:
=简单变量|表达式简单变量:
=标识符|无符号整数在计算机中,表达式的三种标识方
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 队列
![提示](https://static.bdocx.com/images/bang_tan.gif)