栈和队列答案Word格式文档下载.docx
- 文档编号:22549304
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:48
- 大小:51.59KB
栈和队列答案Word格式文档下载.docx
《栈和队列答案Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《栈和队列答案Word格式文档下载.docx(48页珍藏版)》请在冰豆网上搜索。
intd;
InitStack(T);
StackEmpty(S)){
Pop(S,d);
if(d!
=e)Push(T,d);
}
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<
j<
k使
<
。
这个问题和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
#-
B*C/D+E^F#
PUSH(OPND,B)
4
AB
*C/D+E^F#
PUSH(OPTR,*)
5
#-*
C/D+E^F#
PUSH(OPND,C)
6
ABC
/D+E^F#
Operate(B,*,C)
7
AG
PUSH(OPTR,/)
8
#-/
D+E^F#
PUSH(OPND,D)
9
AGD
+E^F#
Operate(G,/,D)
10
AH
Operate(A,-,H)
11
I
PUSH(OPTR,+)
12
#+
E^F#
PUSH(OPND,E)
13
IE
^F#
PUSH(OPTR,^)
14
#+^
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<
i--;
voidditui(intj)
{
if(j>
1){
cout<
j;
ditui(j-1);
return;
}
3.10试将下列递归过程改写为非递归过程。
voidtest(int&
sum)
intx;
cin>
>
x;
if(x==0)sum=0;
else
test(sum);
sum+=x;
sum;
voidtest(int&
Stacks;
InitStack(s);
intx;
do{
Push(s,x);
}while(x>
0);
while(!
StackEmpty(s)){
Pop(s,x);
sum+=x;
sum<
endl;
DestoryStack(s);
3.11简述队列和堆栈这两种数据类型的相同点和差异处。
栈是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。
队列也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。
3.12写出以下程序段的输出结果(队列中的元素类型QElemType为char)。
QueueQ;
InitQueue(Q);
charx=‘e’,y=‘c’;
EnQueue(Q,‘h’);
EnQueue(Q,‘r’);
EnQueue(Q,y);
DeQueue(Q,x);
EnQueue(Q,x);
EnQueue(Q,‘a’);
While(!
QueueEmpty(Q))
DeQueue(Q,y);
y;
char
3.13简述以下算法的功能(栈和队列的元素类型均为int)。
voidalgo3(Queue&
Q)
intd;
DeQueue(Q,d);
Push(S,d);
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]<
p+stacksize-1)*++top[1]=x;
ElemTypePop(inti)
if(top[0]<
top[1])return*++top[0];
Stackempty!
}else{
if(top[1]>
top[0])return*top[1]--;
returnOK;
};
//链栈的数据结构及方法的定义
typedefstructNodeType{
ElemTypedata;
NodeType*next;
}NodeType,*LinkType;
typedefstruct{
LinkTypetop;
intsize;
}Stack;
voidInitStack(Stack&
s)
s.top=NULL;
s.size=0;
voidDestroyStack(Stack&
LinkTypep;
while(s.top){
p=s.top;
s.top=p->
next;
deletep;
s.size--;
voidClearStack(Stack&
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;
StatusPush(Stack&
s,ElemTypee)
p=newNodeType;
p->
next=s.top;
s.top=p;
data=e;
s.size++;
returnOK;
StatusPop(Stack&
s,ElemType&
if(s.top){
//从栈顶到栈底用Visit()函数遍历栈中每个数据元素
voidStackTraverse(Stacks,Status(*Visit)(ElemTypee))
p=s.top;
while(p)Visit(p->
data);
3.16假设如题3.1所属火车调度站的入口处有n节硬席或软席车厢(分别以H和S表示)等待调度,试编写算法,输出对这n节车厢进行调度的操作(即入栈或出栈操作)序列,以使所有的软席车厢都被调整到硬席车厢之前。
intmain()
charBuffer[80];
inti=0,j=0;
cout<
请输入硬席(H)和软席车厢(S)序列:
cin>
Buffer;
Buffer<
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++;
return0;
3.17试写一个算法,识别一次读入的一个以@为结束符的字符序列是否为形如‘序列1&
序列2’模式的字符序列。
其中序列1和序列2中都不含字符‘&
’,且序列2是序列1的逆序列。
例如,‘a+b&
b+a’是属该模式的字符序列,而‘1+3&
3-1’则不是。
BOOLSymmetry(chara[])
inti=0;
ElemTypex;
while(a[i]!
='
&
'
&
a[i]){
Push(s,a[i]);
if(a[i])returnFALSE;
i++;
while(a[i]){
if(x!
=a[i]){
DestroyStack(s);
returnFALSE;
returnTRUE;
3.18试写一个判别表达式中开、闭括号是否配对出现的算法。
BOOLBracketCorrespondency(chara[])
switch(a[i]){
case'
('
:
Push(s,a[i]);
break;
['
)'
GetTop(s,x);
if(x=='
)Pop(s,x);
elsereturnFALSE;
]'
default:
if(s.size!
=0)returnFALSE;
3.20假设以二维数组g(1…m,1…n)表示一个图像区域,g[i,j]表示该区域中点(i,j)所具颜色,其值为从0到k的整数。
编写算法置换点(i0,j0)所在区域的颜色。
约定和(i0,j0)同色的上、下、左、右的邻接点为同色区域的点。
#include<
iostream.h>
stdlib.h>
inty;
}PosType;
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);
CreateGDS(g);
ShowGraphArray(g);
PosTypeStartPos;
StartPos.x=5;
StartPos.y=5;
intFillColor=6;
RegionFilling(g,StartPos,FillColor);
voidRegionFilling(ElemTypeg[M][N],PosTypeCurPos,intFillColor)
ElemTypee;
intOldColor=g[CurPos.x][CurPos.y].Color;
Push(s,g[CurPos.x][CurPos.y]);
Pop(s,e);
CurPos=e.seat;
g[CurPos.x][CurPos.y].Color=FillColor;
g[CurPos.x][CurPos.y].Visited=1;
if(CurPos.x<
M&
!
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<
N&
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>
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;
M;
i++)
for(j=0;
N;
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;
5;
for(j=2;
4;
j++)
g[i][j].Color=3;
for(i=5;
M-1;
for(j=3;
6;
voidShowGraphArray(ElemTypeg[M][N])
i++){
g[i][j].Color;
3.21假设表达式有单字母变量和双目四则运算符构成。
试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰表达式。
//输入的表达式串必须为#...#格式
voidInversePolandExpression(charBuffer[])
Push(s,Buffer[i]);
while(Buffer[i]!
#'
IsOperator(Buffer[i])){//是操作数
i++;
else{//是操作符
GetTop(s,e);
if(Prior(e,Buffer[i])){//当栈顶优先权高于当前序列时,退栈
Pop(s,e);
Buffer[j]=e;
j++;
else{
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 队列 答案