栈和队列答案.docx

上传人:b****6 文档编号:7809199 上传时间:2023-01-26 格式:DOCX 页数:34 大小:48.93KB
下载 相关 举报
栈和队列答案.docx_第1页
第1页 / 共34页
栈和队列答案.docx_第2页
第2页 / 共34页
栈和队列答案.docx_第3页
第3页 / 共34页
栈和队列答案.docx_第4页
第4页 / 共34页
栈和队列答案.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

栈和队列答案.docx

《栈和队列答案.docx》由会员分享,可在线阅读,更多相关《栈和队列答案.docx(34页珍藏版)》请在冰豆网上搜索。

栈和队列答案.docx

栈和队列答案

若按教科书3.1.1节中图(b)所示铁道进行车厢调度(注意:

两侧铁道均为单向行驶道),则请回答:

(1)如果进站的车厢序列为123,则可能得到的出站车厢序列是什么?

(2)如果进站的车厢序列为123456,则能否得到435612和135426的出站序列,并请说明为什么不能得到或者如何得到(即写出以‘S’表示进栈和以‘X’表示出栈的栈操作序列)。

解:

(1)123231321213132

(2)可以得到135426的出站序列,但不能得到435612的出站序列。

因为4356出站说明12已经在栈中,1不可能先于2出栈。

简述栈和线性表的差别。

解:

线性表是具有相同特性的数据元素的一个有限序列。

栈是限定仅在表尾进行插入或删除操作的线性表。

写出下列程序段的输出结果(栈的元素类型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

简述以下算法的功能(栈的元素类型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,将其从栈中清除

假设以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……,说明两个不同的合法栈操作序列的输出元素的序列一定不同。

试证明:

若借助栈由输入序列12…n得到的输出序列为

(它是输入序列的一个排列),则在输出序列中不可能出现这样的情形:

存在着i

<

<

解:

这个问题和题比较相似。

因为输入序列是从小到大排列的,所以若

<

<

,则可以理解为通过输入序列

可以得到输出序列

,显然通过序列123是无法得到312的,参见题。

所以不可能存在着i

<

<

按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,并仿照教科书节例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

试推导求解n阶梵塔问题至少要执行的move操作的次数。

解:

试将下列递推过程改写为递归过程。

voidditui(intn)

{

inti;

i=n;

while(i>1)

cout<

}

解:

voidditui(intj)

{

if(j>1){

cout<

ditui(j-1);

}

return;

}

试将下列递归过程改写为非递归过程。

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);

}

简述队列和堆栈这两种数据类型的相同点和差异处。

解:

栈是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。

队列也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。

写出以下程序段的输出结果(队列中的元素类型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

简述以下算法的功能(栈和队列的元素类型均为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);

}

}

解:

队列逆置

若以1234作为双端队列的输入序列,试分别求出满足以下条件的输出序列:

(1)能由输入受限的双端队列得到,但不能由输出受限的双端队列得到的输出序列。

(2)能由输出受限的双端队列得到,但不能由输入受限的双端队列得到的输出序列。

(3)既不能由输入受限的双端队列得到,也不能由输出受限的双端队列得到的输出序列。

假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两个栈,它们的栈底分别设在数组的两个端点。

试编写实现这个双向栈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;

}

};

2’-1’olor;

Push(s,g[][]);

while(!

StackEmpty(s)){

Pop(s,e);

CurPos=;

g[][].Color=FillColor;

g[][].Visited=1;

if

!

g[+1][].Visited&&

g[+1][].Color==OldColor

Push(s,g[+1][]);

if>0&&

!

g[][].Visited&&

g[][].Color==OldColor

Push(s,g[][]);

if

!

g[][+1].Visited&&

g[][+1].Color==OldColor

Push(s,g[][+1]);

if>0&&

!

g[][].Visited&&

g[][].Color==OldColor

Push(s,g[][]);

}

}

voidCreateGDS(ElemTypeg[M][N])

{

inti,j;

for(i=0;i

for(j=0;j

g[i][j].=i;

g[i][j].=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<

}

}

假设表达式有单字母变量和双目四则运算符构成。

试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰表达式。

解:

.#格式

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{

Push(s,Buffer[i]);

i++;

}

}

}

while(!

StackEmpty(s)){

Pop(s,e);

Buffer[j]=e;

j++;

}

}

StatusIsOpertor(charc)

{

char*p="#+-*/";

while(*p){

if(*p==c)

returnTRUE;

p++;

}

returnFALSE;

}

StatusPrior(charc1,charc2)

{

charch[]="#+-*/";

inti=0,j=0;

while(ch[i]&&ch[i]!

=c1)i++;

if(i==2)i--;//加和减可认为是同级别的运算符

if(i==4)i--;//乘和除可认为是同级别的运算符

while(ch[j]&&ch[j]!

=c2)j++;

if(j==2)j--;

if(j==4)j--;

if(i>=j)returnTRUE;

elsereturnFALSE;

}

如题的假设条件,试写一个算法,对以逆波兰式表示的表达式求值。

解:

charCalVal_InverPoland(charBuffer[])

{

StackOpnd;

InitStack(Opnd);

inti=0;

charc;

ElemTypee1,e2;

while(Buffer[i]!

='#'){

if(!

IsOperator(Buffer[i])){

Push(Opnd,Buffer[i]);

}

else{

Pop(Opnd,e2);

Pop(Opnd,e1);

c=Cal(e1,Buffer[i],e2);

Push(Opnd,c);

}

i++;

}

returnc;

}

charCal(charc1,charop,charc2)

{

intx,x1,x2;

charch[10];

ch[0]=c1;

ch[1]='\0';

x1=atoi(ch);

ch[0]=c2;

ch[1]='\0';

x2=atoi(ch);

switch(op){

case'+':

x=x1+x2;

break;

case'-':

x=x1-x2;

break;

case'*':

x=x1*x2;

break;

case'/':

x=x1/x2;

break;

default:

break;

}

itoa(x,ch,10);

returnch[0];

}

如题的假设条件,试写一个算法,判断给定的非空后缀表达式是否为正确的逆波兰表达式,如果是,则将它转化为波兰式。

解:

#include<>

#include<>

#include<>

#include"d:

\VC99\"

typedefcharARRAY[30];

typedefARRAYElemType;

typedefstructNodeType{

ElemTypedata;

NodeType*next;

}NodeType,*LinkType;

typedefstruct{

LinkTypetop;

intsize;

}Stack;

voidInitStack(Stack&s);

StatusPush(Stack&s,ElemTypee);

StatusPop(Stack&s,ElemTypee);

StatusIsOperator(charc);

StatusStackEmpty(Stacks);

StatusInvToFroPoland(chara[]);

intmain()

{

chara[30];

cout<<"请输入逆波兰算术表达式字符序列:

";

cin>>a;

if(InvToFroPoland(a))cout<

elsecout<<"输入逆波兰算术表达式字符序列错误!

";

return0;

}

StatusInvToFroPoland(chara[])

{

Stacks;

InitStack(s);

inti=0;

ElemTypech;

ElemTypec1;

ElemTypec2;

while(a[i]!

='#'){

if(!

IsOperator(a[i])){

if(a[i]>='0'&&a[i]<='9'){

ch[0]=a[i];ch[1]='\0';

Push(s,ch);

}

elsereturnFALSE;

}

else{

ch[0]=a[i];

ch[1]='\0';

if(!

StackEmpty(s)){

Pop(s,c2);

if(!

StackEmpty(s)){

Pop(s,c1);

strcat(ch,c1);

strcat(ch,c2);

Push(s,ch);

}

elsereturnFALSE;

}

elsereturnFALSE;

}

i++;

}

if(!

StackEmpty(s)){

Pop(s,c1);

strcpy(a,c1);

}

elsereturnFALSE;

if(!

StackEmpty(s))returnFALSE;

returnOK;

}

voidInitStack(Stack&s)

{

=NULL;

=0;

}

StatusPush(Stack&s,ElemTypee)

{

LinkTypep;

p=newNodeType;

if(!

p)exit(OVERFLOW);

p->next=;

=p;

strcpy(p->data,e);

++;

returnOK;

}

StatusPop(Stack&s,ElemTypee)

{

LinkTypep;

if{

strcpy(e,>data);

p=;

=p->next;

deletep;

;

}

returnOK;

}

StatusStackEmpty(Stacks)

{

if==0)returnTRUE;

elsereturnFALSE;

}

StatusIsOperator(charc)

{

char*p="#+-*/";

while(*p){

if(*p==c)

returnTRUE;

p++;

}

returnFALSE;

}

试编写如下定义的递归函数的递归算法,并根据算法画出求g(5,2)时栈的变化过程。

解:

intg(intm,intn);

intmain()

{

intm,n;

cout<<"请输入m和n的值:

";

cin>>m>>n;

if(n>=0)cout<

elsecout<<"NoSolution!

";

return0;

}

intg(intm,intn)

{

if(m>0)

return(g(m-1,2*n)+n);

elsereturn0;

}

假设主函数的返回地址为0,递归函数3条语句的地址分别为1、2、3。

3

0

64

3

1

32

3

2

16

3

3

8

3

4

4

0

5

2

试写出求递归函数F(n)的递归算法,并消除递归:

解:

#include<>

#defineN20

intmain()

{

inti;

inta[N];

intn;

cout<<"请输入n:

";

cin>>n;

for(i=0;i

if(i<1)a[i]=1;

elsea[i]=i*a[i/2];

}

cout<

return0;

}

求解平方根

的迭代函数定义如下:

其中,p是A的近似平方根,e是结果允许误差。

试写出相应的递归算法,并消除递归。

解:

#include<>

doubleSqrt(double

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1