栈和队列答案汇总.docx
- 文档编号:10591563
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:48
- 大小:52.61KB
栈和队列答案汇总.docx
《栈和队列答案汇总.docx》由会员分享,可在线阅读,更多相关《栈和队列答案汇总.docx(48页珍藏版)》请在冰豆网上搜索。
栈和队列答案汇总
3.1若按教科书3.1.1节中图3.1(b)所示铁道进行车厢调度(注意:
两侧铁道均为单向行驶道),则请回答:
(1)如果进站的车厢序列为123,则可能得到的出站车厢序列是什么?
(2)如果进站的车厢序列为123456,则能否得到435612和135426的出站序列,并请说明为什么不能得到或者如何得到(即写出以‘S’表示进栈和以‘X’表示出栈的栈操作序列)。
解:
(1)123231321213132
(2)可以得到135426的出站序列,但不能得到435612的出站序列。
因为4356出站说明12已经在栈中,1不可能先于2出栈。
3.2简述栈和线性表的差别。
解:
线性表是具有相同特性的数据元素的一个有限序列。
栈是限定仅在表尾进行插入或删除操作的线性表。
3.3写出下列程序段的输出结果(栈的元素类型SElemType为char)。
voidmain()
{
StackS;
charx,y;
InitStack(S);
x=‘c’;y=‘k’;
Push(S,x);Push(S,‘a’);Push(S,y);
Pop(S,x);Push(S,‘t’);Push(S,x);
Pop(S,x);Push(S,‘s’);
while(!
StackEmpty(S)){Pop(S,y);printf(y);}
printf(x);
}
解:
stack
3.4简述以下算法的功能(栈的元素类型SElemType为int)。
(1)statusalgo1(StackS)
{
inti,n,A[255];
n=0;
while(!
StackEmpty(S)){n++;Pop(S,A[n]);}
for(i=1;i<=n;i++)Push(S,A[i]);
}
(2)statusalgo2(StackS,inte)
{
StackT;intd;
InitStack(T);
while(!
StackEmpty(S)){
Pop(S,d);
if(d!
=e)Push(T,d);
}
while(!
StackEmpty(T)){
Pop(T,d);
Push(S,d);
}
}
解:
(1)栈中的数据元素逆置
(2)如果栈中存在元素e,将其从栈中清除
3.5假设以S和X分别表示入栈和出栈的操作,则初态和终态均为空栈的入栈和出栈的操作序列可以表示为仅由S和X组成的序列。
称可以操作的序列为合法序列(例如,SXSX为合法序列,SXXS为非法序列)。
试给出区分给定序列为合法序列或非法序列的一般准则,并证明:
两个不同的合法(栈操作)序列(对同一输入序列)不可能得到相同的输出元素(注意:
在此指的是元素实体,而不是值)序列。
解:
任何前n个序列中S的个数一定大于X的个数。
设两个合法序列为:
T1=S……X……S……
T2=S……X……X……
假定前n个操作都相同,从第n+1个操作开始,为序列不同的起始操作点。
由于前n个操作相同,故此时两个栈(不妨为栈A、B)的存储情况完全相同,假设此时栈顶元素均为a。
第n+1个操作不同,不妨T1的第n+1个操作为S,T2的第n+1个操作为X。
T1为入栈操作,假设将b压栈,则T1的输出顺序一定是先b后a;而T2将a退栈,则其输出顺序一定是先a后b。
由于T1的输出为……ba……,而T2的输出顺序为……ab……,说明两个不同的合法栈操作序列的输出元素的序列一定不同。
3.6试证明:
若借助栈由输入序列12…n得到的输出序列为
(它是输入序列的一个排列),则在输出序列中不可能出现这样的情形:
存在着i < < 。 解: 这个问题和3.1题比较相似。 因为输入序列是从小到大排列的,所以若 < < ,则可以理解为通过输入序列 可以得到输出序列 ,显然通过序列123是无法得到312的,参见3.1题。 所以不可能存在着i < < 。 3.7按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,并仿照教科书3.2节例3-2的格式,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程: A-B×C/D+E↑F 解: BC=GG/D=HA-H=IE^F=JI+J=K 步骤 OPTR栈 OPND栈 输入字符 主要操作 1 # A-B*C/D+E^F# PUSH(OPND,A) 2 # A -B*C/D+E^F# PUSH(OPTR,-) 3 #- A B*C/D+E^F# PUSH(OPND,B) 4 #- AB *C/D+E^F# PUSH(OPTR,*) 5 #-* AB C/D+E^F# PUSH(OPND,C) 6 #-* ABC /D+E^F# Operate(B,*,C) 7 #- AG /D+E^F# PUSH(OPTR,/) 8 #-/ AG D+E^F# PUSH(OPND,D) 9 #-/ AGD +E^F# Operate(G,/,D) 10 #- AH +E^F# Operate(A,-,H) 11 # I +E^F# PUSH(OPTR,+) 12 #+ I E^F# PUSH(OPND,E) 13 #+ IE ^F# PUSH(OPTR,^) 14 #+^ IE F# PUSH(OPND,F) 15 #+^ IEF # Operate(E,^,F) 16 #+ IJ # Operate(I,+,J) 17 # K # RETURN 3.8试推导求解n阶梵塔问题至少要执行的move操作的次数。 解: 3.9试将下列递推过程改写为递归过程。 voidditui(intn) { inti; i=n; while(i>1) cout< } 解: voidditui(intj) { if(j>1){ cout< ditui(j-1); } return; } 3.10试将下列递归过程改写为非递归过程。 voidtest(int&sum) { intx; cin>>x; if(x==0)sum=0; else { test(sum); sum+=x; } cout< } 解: voidtest(int&sum) { Stacks; InitStack(s); intx; do{ cin>>x; Push(s,x); }while(x>0); while(! StackEmpty(s)){ Pop(s,x); sum+=x; cout< } DestoryStack(s); } 3.11简述队列和堆栈这两种数据类型的相同点和差异处。 解: 栈是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。 队列也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。 3.12写出以下程序段的输出结果(队列中的元素类型QElemType为char)。 voidmain() { QueueQ; InitQueue(Q); charx=‘e’,y=‘c’; EnQueue(Q,‘h’); EnQueue(Q,‘r’); EnQueue(Q,y); DeQueue(Q,x); EnQueue(Q,x); DeQueue(Q,x); EnQueue(Q,‘a’); While(! QueueEmpty(Q)) { DeQueue(Q,y); cout< } cout< } 解: char 3.13简述以下算法的功能(栈和队列的元素类型均为int)。 voidalgo3(Queue&Q) { StackS; intd; InitStack(S); while(! QueueEmpty(Q)) { DeQueue(Q,d); Push(S,d); } while(! StackEmpty(S)) { Pop(S,d); EnQueue(Q,d); } } 解: 队列逆置 3.14若以1234作为双端队列的输入序列,试分别求出满足以下条件的输出序列: (1)能由输入受限的双端队列得到,但不能由输出受限的双端队列得到的输出序列。 (2)能由输出受限的双端队列得到,但不能由输入受限的双端队列得到的输出序列。 (3)既不能由输入受限的双端队列得到,也不能由输出受限的双端队列得到的输出序列。 3.15假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两个栈,它们的栈底分别设在数组的两个端点。 试编写实现这个双向栈tws的三个操作: 初始化inistack(tws)、入栈push(tws,i,x)和出栈pop(tws,i)的算法,其中i为0或1,用以分别指示设在数组两端的两个栈,并讨论按过程(正/误状态变量可设为变参)或函数设计这些操作算法各有什么有缺点。 解: classDStack{ ElemType*top[2]; ElemType*p; intstacksize; intdi; public: DStack(intm) { p=newElemType[m]; if(! p)exit(OVERFLOW); top[0]=p+m/2; top[1]=top[0]; stacksize=m; } ~DStack(){deletep;} voidPush(inti,ElemTypex) { di=i; if(di==0){ if(top[0]>=p)*top[0]--=x; elsecerr<<"Stackoverflow! "; } else{ if(top[1] elsecerr<<"Stackoverflow! "; } } ElemTypePop(inti) { di=i; if(di==0){ if(top[0] elsecerr<<"Stackempty! "; }else{ if(top[1]>top[0])return*top[1]--; elsecerr<<"Stackempty! "; } returnOK; } }; //链栈的数据结构及方法的定义 typedefstructNodeType{ ElemTypedata; NodeType*next; }NodeType,*LinkType; typedefstruct{ LinkTypetop; intsize; }Stack; voidInitStack(Stack&s) { s.top=NULL; s.size=0; } voidDestroyStack(Stack&s) { LinkTypep; while(s.top){ p=s.top; s.top=p->next; deletep; s.size--; } } voidClearStack(Stack&s) { LinkTypep; while(s.top){ p=s.top; s.top=p->next; deletep; s.size--; } } intStackLength(Stacks) { returns.size; } StatusStackEmpty(Stacks) { if(s.size==0)returnTRUE; elsereturnFALSE; } StatusGetTop(Stacks,ElemType&e) { if(! s.top)returnERROR; else{ e=s.top->data; returnOK; } } StatusPush(Stack&s,ElemTypee) { LinkTypep; p=newNodeType; if(! p)exit(OVERFLOW); p->next=s.top; s.top=p; p->data=e; s.size++; returnOK; } StatusPop(Stack&s,ElemType&e) { LinkTypep; if(s.top){ e=s.top->data; p=s.top; s.top=p->next; deletep; s.size--; } returnOK; } //从栈顶到栈底用Visit()函数遍历栈中每个数据元素 voidStackTraverse(Stacks,Status(*Visit)(ElemTypee)) { LinkTypep; p=s.top; while(p)Visit(p->data); } 3.16假设如题3.1所属火车调度站的入口处有n节硬席或软席车厢(分别以H和S表示)等待调度,试编写算法,输出对这n节车厢进行调度的操作(即入栈或出栈操作)序列,以使所有的软席车厢都被调整到硬席车厢之前。 解: intmain() { Stacks; charBuffer[80]; inti=0,j=0; InitStack(s); cout<<"请输入硬席(H)和软席车厢(S)序列: "; cin>>Buffer; cout< while(Buffer[i]){ if(Buffer[i]=='S'){ Buffer[j]=Buffer[i]; j++; } elsePush(s,Buffer[i]); i++; } while(Buffer[j]){ Pop(s,Buffer[j]); j++; } cout< return0; } 3.17试写一个算法,识别一次读入的一个以@为结束符的字符序列是否为形如‘序列1&序列2’模式的字符序列。 其中序列1和序列2中都不含字符‘&’,且序列2是序列1的逆序列。 例如,‘a+b&b+a’是属该模式的字符序列,而‘1+3&3-1’则不是。 解: BOOLSymmetry(chara[]) { inti=0; Stacks; InitStack(s); ElemTypex; while(a[i]! ='&'&&a[i]){ Push(s,a[i]); i++; } if(a[i])returnFALSE; i++; while(a[i]){ Pop(s,x); if(x! =a[i]){ DestroyStack(s); returnFALSE; } i++; } returnTRUE; } 3.18试写一个判别表达式中开、闭括号是否配对出现的算法。 解: BOOLBracketCorrespondency(chara[]) { inti=0; Stacks; InitStack(s); ElemTypex; while(a[i]){ switch(a[i]){ case'(': Push(s,a[i]); break; case'[': Push(s,a[i]); break; case')': GetTop(s,x); if(x=='(')Pop(s,x); elsereturnFALSE; break; case']': GetTop(s,x); if(x=='[')Pop(s,x); elsereturnFALSE; break; default: break; } i++; } if(s.size! =0)returnFALSE; returnTRUE; } 3.20假设以二维数组g(1…m,1…n)表示一个图像区域,g[i,j]表示该区域中点(i,j)所具颜色,其值为从0到k的整数。 编写算法置换点(i0,j0)所在区域的颜色。 约定和(i0,j0)同色的上、下、左、右的邻接点为同色区域的点。 解: #include #include typedefstruct{ intx; inty; }PosType; typedefstruct{ intColor; intVisited; PosTypeseat; }ElemType; #include"d: \VC99\Stack.h" #defineM8 #defineN8 ElemTypeg[M][N]; voidCreateGDS(ElemTypeg[M][N]); voidShowGraphArray(ElemTypeg[M][N]); voidRegionFilling(ElemTypeg[M][N],PosTypeCurPos,intNewColor); intmain() { CreateGDS(g); ShowGraphArray(g); PosTypeStartPos; StartPos.x=5; StartPos.y=5; intFillColor=6; RegionFilling(g,StartPos,FillColor); cout< ShowGraphArray(g); return0; } voidRegionFilling(ElemTypeg[M][N],PosTypeCurPos,intFillColor) { Stacks; InitStack(s); ElemTypee; intOldColor=g[CurPos.x][CurPos.y].Color; Push(s,g[CurPos.x][CurPos.y]); while(! StackEmpty(s)){ Pop(s,e); CurPos=e.seat; g[CurPos.x][CurPos.y].Color=FillColor; g[CurPos.x][CurPos.y].Visited=1; if(CurPos.x ! g[CurPos.x+1][CurPos.y].Visited&& g[CurPos.x+1][CurPos.y].Color==OldColor ) Push(s,g[CurPos.x+1][CurPos.y]); if(CurPos.x>0&& ! g[CurPos.x-1][CurPos.y].Visited&& g[CurPos.x-1][CurPos.y].Color==OldColor ) Push(s,g[CurPos.x-1][CurPos.y]); if(CurPos.y ! g[CurPos.x][CurPos.y+1].Visited&& g[CurPos.x][CurPos.y+1].Color==OldColor ) Push(s,g[CurPos.x][CurPos.y+1]); if(CurPos.y>0&& ! g[CurPos.x][CurPos.y-1].Visited&& g[CurPos.x][CurPos.y-1].Color==OldColor ) Push(s,g[CurPos.x][CurPos.y-1]); } } voidCreateGDS(ElemTypeg[M][N]) { inti,j; for(i=0;i for(j=0;j g[i][j].seat.x=i; g[i][j].seat.y=j; g[i][j].Visited=0; g[i][j].Color=0; } for(i=2;i<5;i++) for(j=2;j<4;j++) g[i][j].Color=3; for(i=5;i for(j=3;j<6;j++) g[i][j].Color=3; } voidShowGraphArray(ElemTypeg[M][N]) { inti,j; for(i=0;i for(j=0;j cout< cout< } } 3.21假设表达式有单字母变量和双目四则运算符构成。 试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰表达式。 解: //输入的表达式串必须为#...#格式 voidInversePolandExpression(charBuffer[]) { Stacks; InitStack(s); inti=0,j=0; ElemTypee; Push(s,Buffer[i]); i++; while(Buffer[i]! ='#'){ if(! IsOperator(Buffer[i])){//是操作数 Buffer[j]=Buffer[i]; i++; j++; } else{//是操作符 GetTop(s,e); if(Prior(e,Buffer[i])){//当栈顶优先权高于当前序列时,退栈 Pop(s,e); Buffer[j]=e; j++; } else{ Pu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 队列 答案 汇总