第三章 栈和队列习题与解析good.docx

上传人:b****6 文档编号:4021320 上传时间:2022-11-27 格式:DOCX 页数:27 大小:28.39KB
下载 相关 举报
第三章 栈和队列习题与解析good.docx_第1页
第1页 / 共27页
第三章 栈和队列习题与解析good.docx_第2页
第2页 / 共27页
第三章 栈和队列习题与解析good.docx_第3页
第3页 / 共27页
第三章 栈和队列习题与解析good.docx_第4页
第4页 / 共27页
第三章 栈和队列习题与解析good.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

第三章 栈和队列习题与解析good.docx

《第三章 栈和队列习题与解析good.docx》由会员分享,可在线阅读,更多相关《第三章 栈和队列习题与解析good.docx(27页珍藏版)》请在冰豆网上搜索。

第三章 栈和队列习题与解析good.docx

第三章栈和队列习题与解析good

第四章栈和队列习题

一判断题(y/n)nyynnynnn

1做进栈运算时应先判别,栈是否为空。

2,做退栈运算时应先判别,栈是否为空。

3,当栈中元素为n个,作进栈运算时发生上溢,则说明该栈的最大容量为n.

4,为了增加内存空间的利用率和减少发生上溢的可能性,由两个栈共享一片连续的内存空间时,应将两栈的栈顶分别设在着片内存空间的两端。

5,只有当两个基本栈的栈底在栈空间的某一位置相遇时,才产生上溢。

6,栈是一种线性表,它的特点是后进先出。

7,设一数列的顺序为1,2,3,4,5,6,通过栈结构可以排成的顺序必须是3,2,5,6,4,1.

8,设有一个空栈,栈顶指针为1000H(十六进制,下同),现有输入序列1,2,3,4,5,经过PUSH,PUSH,POP,PUSH,POP,PUSH,PUSH后,输出序列是2,1.

9,设有一个空栈,栈顶指针为1000H(十六进制,下同),现有输入序列1,2,3,4,5,经过PUSH,PUSH,POP,PUSH,POP,PUSH,PUSH后,栈顶指针是不是1005H.

二单选题(请从下列A,B,C,D选项中选择一项)

1,栈的特点是:

先进先出

后进先出

进优于出

出优于进

2,队列的特点是:

先进先出

后进先出

进优于出

出优于进

3,栈与队列都是:

顺序存储的线性结构

链式存储的线性结构

限制存取点的线性结构

限制存取点的非线性结构

4,若进栈序列为1,2,3,4,则()不可能是一个出栈序列。

3,2,1,4

3,2,4,1

4,2,3,1

4,3,2,1

1,2,3,4

1,3,2,4

5,若进栈队列的序列为1,2,3,4,则()是一个出队列序列。

3,2,1,4

3,2,4,1

4,2,3,1

4,3,2,1

1,2,3,4

1,3,2,4

6,若一个栈的输入序列是:

1,2,3,...,n,输出序列的第一个元素是n,则第i个输出元素是:

不确定

n-i

n-i+1

i

n-i-1

三编程题

1,以flag为标志位,写出循环队列中插入算法

2,以flag为标志位,写出循环队列中删除算法

4-2改写顺序栈的进栈成员函数Push(x),要求当栈满时执行一个stackFull()操作进行栈满处理。

其功能是:

动态创建一个比原来的栈数组大二倍的新数组,代替原来的栈数组,原来栈数组中的元素占据新数组的前MaxSize位置。

【解答】templatevoidstack:

:

push(constType&item){

if(isFull())stackFull();//栈满,做溢出处理

elements[++top]=item;//进栈

 

}

 

templatevoidstack:

:

stackFull(){

Type*temp=newType[2*maxSize];//创建体积大一倍的数组

 

for(inti=0;i<=top;i++)//传送原数组的数据

temp[i]=elements[i];

delete[]elements;//删去原数组

maxSize*=2;//数组最大体积增长一倍

elements=temp;//新数组成为栈的数组空间

 

}

 

4-3铁路进行列车调度时,常把站台设计成栈式结构的站台,如右图所示。

试问:

(1)设有编号为1,2,3,4,5,6的六辆列车,顺序开入栈式结构的站台,则可能的出栈序列有多少种?

(2)若进站的六辆列车顺序如上所述,那么是否能够得到435612,325641,154623和135426的出站序列,如果不能,说明为什么不能;如果能,说明如何得到(即写出"进栈"或"出栈"的序列)。

【解答】

(1)可能的不同出栈序列有种。

(2)不能得到435612和154623这样的出栈序列。

因为若在4,3,5,6之后再将1,2出栈,则1,2必须一直在栈中,此时1先进栈,2后进栈,2应压在1上面,不可能1先于2出栈。

154623也是这种情况。

出栈序列325641和135426可以得到。

 

 

3

 

 

 

 

 

5

 

 

 

6

 

 

 

 

 

 

2

 

2

 

 

 

4

 

4

 

4

 

4

 

 

 

 

1

 

1

 

1

 

1

 

1

 

1

 

1

 

1

 

 

 

33232325325325632564325641

 

 

 

 

 

 

 

 

5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3

 

4

 

4

 

 

 

 

 

 

 

 

1

 

 

 

2

 

2

 

2

 

2

 

 

 

6

 

 

 

1113135********213542135426

 

4-4试证明:

若借助栈可由输入序列1,2,3,…,n得到一个输出序列p1,p2,p3,…,pn(它是输入序列的某一种排列),则在输出序列中不可能出现以下情况,即存在i

(提示:

用反证法)

【解答】

因为借助栈由输入序列1,2,3,…,n,可得到输出序列p1,p2,p3,…,pn,如果存在下标i,j,k,满足i

¬i进栈,i出栈,j进栈,j出栈,k进栈,k出栈。

此时具有最小值的排在最前面pi位置,具有中间值的排在其后pj位置,具有最大值的排在pk位置,有pi

i进栈,i出栈,j进栈,k进栈,k出栈,j出栈。

此时具有最小值的排在最前面pi位置,具有最大值的排在pj位置,具有中间值的排在最后pk位置,有pi

®i进栈,j进栈,j出栈,i出栈,k进栈,k出栈。

此时具有中间值的排在最前面pi位置,具有最小值的排在其后pj位置,有pj

¯i进栈,j进栈,j出栈,k进栈,k出栈,i出栈。

此时具有中间值的排在最前面pi位置,具有最大值的排在其后pj位置,具有最小值的排在pk位置,有pk

°i进栈,j进栈,k进栈,k出栈,j出栈,i出栈。

此时具有最大值的排在最前面pi位置,具有中间值的排在其后pj位置,具有最小值的排在pk位置,有pk

 

4-5写出下列中缀表达式的后缀形式:

(1)A*B*C

(2)-A+B-C+D

(3)A*-B+C

(4)(A+B)*D+E/(F+A*D)+C

(5)A&&B||!

(E>F){注:

按C++的优先级)

(6)!

(A&&!

((BD)))||(C

【解答】

(1)AB*C*

(2)A-B+C-D+

(3)AB-*C+

(4)AB+D*EFAD*+/C+

(5)AB&&EF>!

||

(6)ABC||!

&&!

CE<||

 

4-7设表达式的中缀表示为a*x-b/x↑2,试利用栈将它改为后缀表示ax*bx2↑/-。

写出转换过程中栈的变化。

【解答】

 

步序

扫描项

项类型

动作

栈的变化

输出

0

 

 

☞'#'进栈,读下一符号

#

 

1

a

操作数

☞直接输出,读下一符号

#

a

2

*

操作符

☞isp('#')

#*

a

3

x

操作数

☞直接输出,读下一符号

#*

ax

4

-

操作符

☞isp('*')>icp('-'),退栈输出

#

ax*

 

 

 

☞isp('#')

#-

ax*

5

b

操作数

☞直接输出,读下一符号

#-

ax*b

6

/

操作符

☞isp('-')

#-/

ax*b

7

x

操作数

☞直接输出,读下一符号

#-/

ax*bx

8

操作符

☞isp('/')

#-/↑

ax*bx

9

2

操作数

☞直接输出,读下一符号

#-/↑

ax*bx2

10

#

操作符

☞isp('↑')>icp('#'),退栈输出

#-/

ax*bx2↑

 

 

 

☞isp('/')>icp('#'),退栈输出

#-

ax*bx2↑/

 

 

 

☞isp('-')>icp('#'),退栈输出

#

ax*bx2↑/-

 

 

 

F结束

 

 

 

 

4-9假设以数组Q[m]存放循环队列中的元素,同时以rear和length分别指示环形队列中的队尾位置和队列中所含元素的个数。

试给出该循环队列的队空条件和队满条件,并写出相应的插入(enqueue)和删除(dlqueue)元素的操作。

【解答】

循环队列类定义

#include

templateclassQueue{//循环队列的类定义

 

public:

Queue(int=10);

~Queue(){delete[]elements;}

voidEnQueue(Type&item);

TypeDeQueue();

TypeGetFront();

voidMakeEmpty(){length=0;}//置空队列

intIsEmpty()const{returnlength==0;}//判队列空否

intIsFull()const{returnlength==maxSize;}//判队列满否

 

private:

intrear,length;//队尾指针和队列长度

Type*elements;//存放队列元素的数组

intmaxSize;//队列最大可容纳元素个数

 

}

构造函数

template

Queue:

:

Queue(intsz):

rear(maxSize-1),length(0),maxSize(sz){

//建立一个最大具有maxSize个元素的空队列。

elements=newType[maxSize];//创建队列空间

assert(elements!

=0);//断言:

动态存储分配成功与否

 

}

插入函数

template

voidQueue:

:

EnQueue(Type&item){

assert(!

IsFull());//判队列是否不满,满则出错处理

length++;//长度加1

rear=(rear+1)%maxSize;//队尾位置进1

 

elements[rear]=item;//进队列

 

}

删除函数

template

TypeQueue:

:

DeQueue(){

assert(!

IsEmpty());//判断队列是否不空,空则出错处理

length--;//队列长度减1

returnelements[(rear-length+maxSize)%maxSize];//返回原队头元素值

 

}

读取队头元素值函数

template

TypeQueue:

:

GetFront(){

assert(!

IsEmpty());

returnelements[(rear-length+1+maxSize)%maxSize];//返回队头元素值

 

}

 

4-10假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag==0和tag==1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。

试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。

【解答】

循环队列类定义

#include

templateclassQueue{//循环队列的类定义

 

public:

Queue(int=10);

~Queue(){delete[]Q;}

voidEnQueue(Type&item);

TypeDeQueue();

TypeGetFront();

voidMakeEmpty(){front=rear=tag=0;}//置空队列

intIsEmpty()const{returnfront==rear&&tag==0;}//判队列空否

intIsFull()const{returnfront==rear&&tag==1;}//判队列满否

 

private:

intrear,front,tag;//队尾指针、队头指针和队满标志

Type*Q;//存放队列元素的数组

intm;//队列最大可容纳元素个数

 

}

构造函数

template

Queue:

:

Queue(intsz):

rear(0),front(0),tag(0),m(sz){

//建立一个最大具有m个元素的空队列。

Q=newType[m];//创建队列空间

assert(Q!

=0);//断言:

动态存储分配成功与否

 

}

插入函数

template

voidQueue:

:

EnQueue(Type&item){

assert(!

IsFull());//判队列是否不满,满则出错处理

rear=(rear+1)%m;//队尾位置进1,队尾指针指示实际队尾位置

Q[rear]=item;//进队列

tag=1;//标志改1,表示栈不空

 

}

删除函数

template

TypeQueue:

:

DeQueue(){

assert(!

IsEmpty());//判断队列是否不空,空则出错处理

front=(front+1)%m;//队头位置进1,队头指针指示实际队头的前一位置

tag=0;//标志改0,表示栈不满

returnQ[front];//返回原队头元素的值

 

}

读取队头元素函数

template

TypeQueue:

:

GetFront(){

assert(!

IsEmpty());//判断队列是否不空,空则出错处理

returnQ[(front+1)%m];//返回队头元素的值

 

}

 

4-11若使用循环链表来表示队列,p是链表中的一个指针。

试基于此结构给出队列的插入(enqueue)和删除(dequeue)算法,并给出p为何值时队列空。

【解答】

链式队列的类定义

templateclassQueue;//链式队列类的前视定义

 

 

templateclassQueueNode{//链式队列结点类定义

 

friendclassQueue;

private:

Typedata;//数据域

QueueNode*link;//链域

QueueNode(Typed=0,QueueNode*l=NULL):

data(d),link(l){}//构造函数

 

};

 

 

templateclassQueue{//链式队列类定义

 

public:

Queue():

p(NULL){}//构造函数

~Queue();//析构函数

voidEnQueue(constType&item);//将item加入到队列中

TypeDeQueue();//删除并返回队头元素

TypeGetFront();//查看队头元素的值

voidMakeEmpty();//置空队列,实现与~Queue()相同

intIsEmpty()const{returnp==NULL;}//判队列空否

private:

QueueNode*p;//队尾指针(在循环链表中)

 

};

队列的析构函数

templateQueue:

:

~Queue(){//队列的析构函数

QueueNode*s;

while(p!

=NULL){s=p;p=p→link;deletes;}//逐个删除队列中的结点

 

}

队列的插入函数

templatevoidQueue:

:

EnQueue(constType&item){

if(p==NULL){//队列空,新结点成为第一个结点

p=newQueueNode(item,NULL);p→link=p;

 

}

else{//队列不空,新结点链入p之后

QueueNode*s=newQueueNode(item,NULL);

s→link=p→link;p=p→link=s;//结点p指向新的队尾

 

}

}

队列的删除函数

templateTypeQueue:

:

DeQueue(){

if(p==NULL){cout<<"队列空,不能删除!

"<

QueueNode*s=p;//队头结点为p后一个结点

p→link=s→link;//重新链接,将结点s从链中摘下

Typeretvalue=s→data;deletes;//保存原队头结点中的值,释放原队头结点

returnretvalue;//返回数据存放地址

 

}

队空条件p==NULL。

 

4-12若将一个双端队列顺序表示在一维数组V[m]中,两个端点设为end1和end2,并组织成一个循环队列。

试写出双端队列所用指针end1和end2的初始化条件及队空与队满条件,并编写基于此结构的相应的插入(enqueue)新元素和删除(dlqueue)算法。

【解答】

初始化条件end1=end2=0;

队空条件end1=end2;

队满条件(end1+1)%m=end2;//设end1端顺时针进栈,end2端逆时针进栈

循环队列类定义

#include

templateclassDoubleQueue{//循环队列的类定义

 

public:

DoubleQueue(int=10);

~DoubleQueue(){delete[]V;}

voidEnQueue(Type&item,constintend);

TypeDeQueue(constintend);

TypeGetFront(constintend);

voidMakeEmpty(){end1=end2=0;}//置空队列

intIsEmpty()const{returnend1==end2;}//判两队列空否

intIsFull()const{return(end1+1)%m==end2;}//判两队列满否

 

private:

intend1,end2;//队列两端的指针

Type*V;//存放队列元素的数组

intm;//队列最大可容纳元素个数

 

}

构造函数

template

DoubleQueue:

:

DoubleQueue(intsz):

end1(0),end2(0),m(sz){

//建立一个最大具有m个元素的空队列。

V=newType[m];//创建队列空间

assert(V!

=0);//断言:

动态存储分配成功与否

 

}

插入函数

template

voidDoubleQueue:

:

EnQueue(Type&item,constintend){

assert(!

IsFull());

if(end==1){

end1=(end1+1)%m;//end1端指针先进1,再按指针进栈

V[end1]

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

当前位置:首页 > 自然科学 > 天文地理

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

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