第三章栈和队列习题答案Word文档格式.docx
- 文档编号:20071827
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:12
- 大小:20.96KB
第三章栈和队列习题答案Word文档格式.docx
《第三章栈和队列习题答案Word文档格式.docx》由会员分享,可在线阅读,更多相关《第三章栈和队列习题答案Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
因为是循环链表,尾
指针所指的下一个元素就是头指针所指元素,所以出队时不需要遍历整个队列。
3.5指出下述程序段的功能是什么?
(1)voidDemo1(SeqStack*S){
inti;
arr[64];
n=0;
while(StackEmpty(S))arr[n++]=Pop(S);
for(i=0,i<
n;
i++)Push(S,arr[i]);
}//Demo1
(2)SeqStackS1,S2,tmp;
DataTypex;
...//假设栈tmp和S2已做过初始化
while(!
StackEmpty(&
S1)){x=Pop(&
S1);
Push(&
tmp,x);
}
tmp))
{x=Pop(&
tmp);
Push(&
S1,x);
S2,x);
(3)voidDemo2(SeqStack*S,intm)
{//设DataType为int型
SeqStackT;
inti;
InitStack(&
T);
while(!
StackEmpty(S))
if((i=Pop(S))!
=m)Push(&
T,i);
StackEmpty(&
T))
{
i=Pop(&
Push(S,i);
(4)voidDemo3(CirQueue*Q)
{//设DataType为int型intx;
SeqStackS;
InitStack(&
S);
QueueEmpty(Q))
{x=DeQueue(Q);
Push(&
S,x);
}while(!
s))
{x=Pop(&
EnQueue(Q,x);
}//Demo3
(5)CirQueueQ1,Q2;
//设DataType为int型
intx,i,n=0;
...//设Q1已有内容,Q2已初始化过while(!
QueueEmpty(&
Q1))
{x=DeQueue(&
Q1);
EnQueue(&
Q2,x);
n++;
}for(i=0;
i<
i++)
{x=DeQueue(&
Q2);
EnQueue(&
Q1,x);
EnQueue(&
(1)
也就是原来在栈顶的元素放到栈底,栈底的
程序段的功能是将一栈中的元素按反序重新排列,元素放到栈顶。
此栈中元素个数限制在64个以内。
(2)程序段的功能是利用tmp栈将一个非空栈s1的所有元素按原样复制到一个栈s2当中去。
(3)程序段的功能是利用栈T,将一个非空栈S中值等于m的元素全部删去。
(4)程序段的功能是将一个循环队列Q经过S栈的处理,反向排列,原来的队头变成队尾,原来
的队尾变成队头。
(5)这段程序的功能是将队列1的所有元素复制到队列2中去,但其执行过程是先把队列1的元素全部出队,进入队列2,然后再把队列2的元素复制到队列1中。
二、算法设计题
3.6回文是指正读反读均相同的字符序列,如"
abba"
和"
abdba"
均是回文,但"
good"
不是回文。
试写一
个算法判定给定的字符向量是否为回文。
(提示:
将一半字符入栈)
解:
根据提示,算法可设计为:
//以下为顺序栈的存储结构定义
#defineStackSize100//假定预分配的栈空间最多为100个元素
typedefcharDataType;
//假定栈元素的数据类型为字符
typedefstruct{
DataTypedata[StackSize];
inttop;
}SeqStack;
intIsHuiwen(char*t)
{//判断t字符向量是否为回文,若是,返回1,否则返回0
SeqStacks;
inti,len;
chartemp;
s);
len=strlen(t);
//求向量长度
for(i=0;
len/2;
i++)//将一半字符入栈
s,t[i]);
while(!
EmptyStack(&
{//每弹出一个字符与相应字符比较temp=Pop(&
if(temp!
=S[i])return0;
//不等则返回0
elsei++;
return1;
//比较完毕均相等则返回1
3.7利用栈的基本操作,写一个将栈S中所有结点均删去的算法voidClearStack(SeqStack*S,)并说明S为何要作为指针参数?
算法如下
voidClearStack(SeqStack*S)
{//删除栈中所有结点
S->
Top=-1;
//其实只是将栈置空
因为要置空的是栈S,如果不用指针来做参数传递,那么函数进行的操作不能对原来的栈产生影响,系统将会在内存中开辟另外的单元来对形参进行函数操作。
结果等于什么也没有做。
所以想要把函数操作的结果返回给实参的话,就只能用指针来做参数传递了。
3.8利用栈的基本操作,写一个返回S中结点个数的算法intStackSize(SeqStackS并),说明S为何不作为指针参数?
算法如下:
intStackSize(SeqStackS)
{//计算栈中结点个数
intn=0;
if(!
EmptyStack(&
S)){
Pop(&
n++;
}returnn;
上述算法的目的只要得到S栈的结点个数就可以了。
并不能改变栈的结构。
所以S不用指针做参数,以避免对原来的栈中元素进行任何改变。
系统会把原来的栈按值传递给形参,函数只对形参进行操作,最后返回元素个数。
3.9设计算法判断一个算术表达式的圆括号是否正确配对。
对表达式进行扫描,凡遇到'
('
就
进栈,遇'
)'
就退掉栈顶的'
,表达式被扫描完毕,栈应为空。
根据提示,可以设计算法如下:
intPairBracket(char*SR)
{//检查表达式ST中括号是否配对
SeqStackS;
//定义一个栈
for(i=0;
strlen(SR);
if(S[i]=='
)Push(&
S,SR[i]);
//遇'
时进栈
)//遇'
if(!
StackEmpty(S))//栈不为空时,将栈顶元素出栈Pop(&
elsereturn0;
//不匹配,返回0
ifEmptyStack(&
s)return1;
//匹配,返回1
3.10一个双向栈S是在同一向量空间内实现的两个栈,它们的栈底分别设在向量空间的两端。
试为此双向栈设计初始化InitStack(S)、入栈Push(S,i,x)和出栈Pop(S,i)等算法,其中i为0或1,用以表示栈号。
双向栈其实和单向栈原理相同,只是在一个向量空间内,好比是两个头对头的栈放在一起,中间的空间可以充分利用。
双向栈的算法设计如下:
//双向栈的栈结构类型与以前定义略有不同
#defineStackSize100//假定分配了100个元素的向量空间
#definecharDataType
DataTypeData[StackSize]
inttop0;
//需设两个指针
inttop1;
}DblStack
voidInitStack(DblStack*S)
{//初始化双向栈
top0=-1;
top1=StackSize;
//这里的top2也指出了向量空间,但由于是作为栈底,因此不会出错
intEmptyStack(DblStack*S,inti)
{//判栈空(栈号i)
return(i==0&
&
S->
top0==-1||i==1&
top1==StackSize);
intFullStack(DblStack*S)
{//判栈满,满时肯定两头相遇
return(S->
top0==S-top1-1);
}voidPush(DblStack*S,inti,DataTypex)
{//进栈(栈号i)if(FullStack(S))
Error("
Stackoverflow"
);
//上溢、退出运行
if(i==0)S->
Data[++S->
top0]=x;
//栈0入栈
if(i==1)S->
Data[--S->
top1]=x;
//栈1入栈
DataTypePop(DblStack*S,inti)
{//出栈(栈号i)if(EmptyStack(S,i))
Stackunderflow"
//下溢退出
if(i==0)
return(S->
Data[S->
top0--]);
//返回栈顶元素,指针值减1
if(i==1)
top1++]);
//因为这个栈是以另一端为底的,所以指针值加1。
3.11Ackerman函数定义如下:
请写出递归算法。
┌n+1当m=0时
AKM(m,n)=│AK-M1(,1m)当m≠0,n=0时
≠时0
└AKM(m-1,AKM(m,n-1))当m≠0,n解:
intAKM(intm,intn)
if(m==0)returnn+1;
if(m<
>
0&
n==0)returnAKM(m-1,1);
n<
0)returnAKM(m-1,AKM(m,n-1));
}
3.12
试为其设计置空队,
用第二种方法,即少用一个元素空间的方法来区别循环队列的队空和队满,判队空,判队满、出队、入队及取队头元素等六个基本操作的算法。
解:
算法设计如下:
//循环队列的定义
#defineQueueSize100
typedefcharDatatype;
//设元素的类型为char型
typedefstruct{
intfront;
intrear;
DataTypeData[QueueSize];
}CirQueue;
(1)置空队
voidInitQueue(CirQueue*Q)
{//置空队
Q->
front=Q->
rear=0;
(2)判队空
intEmptyQueue(CirQueue*Q)
{//判队空
returnQ->
front==Q->
rear;
(3)判队满
intFullQueue(CirQueue*Q)
{//判队满//如果尾指针加1后等于头指针,则认为满
return(Q->
rear+1)%QueueSize==Q->
front;
(4)出队
DataTypeDeQueue(CirQueue*Q)
{//出队
DataTypetemp;
if(EmptyQueue(Q))
队已空,无元素可以出队"
temp=Q->
Data[Q->
front];
//保存元素值
front=(Q->
front+1)%QueueSize;
//循环意义上的加1returntemp;
//返回元素值
(5)入队
voidEnQueue(CirQueue*Q,DataTypex)
{//入队
if(FullQueue(Q))
Error("
队已满,不可以入队"
rear]=x;
rear=(Q->
rear+1)%QueueSize;
//rear指向下一个空元素位置
(6)取队头元素
DataTypeFrontQueue(CirQueue*Q)
{//取队头元素
if(EmptyQueue(Q))
Error("
队空,无元素可取"
front];
3.13
(注意不设头指针),
假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素站点试编写相应的置空队、判队空、入队和出队等算法。
//先定义链队结构:
typedefstructqueuenode{
Datatypedata;
structqueuenode*next;
}QueueNode;
//以上是结点类型的定义
queuenode*rear;
}LinkQueue;
//只设一个指向队尾元素的指针
voidInitQueue(LinkQueue*Q)
{//置空队:
就是使头结点成为队尾元素
QueueNode*s;
rear=Q->
rear->
next;
//将队尾指针指向头结点
while(Q->
rear!
=Q->
next)//当队列非空,将队中元素逐个出队{s=Q->
next=s->
free(s);
}//回收结点空间
intEmptyQueue(LinkQueue*Q)
//当头结点的next指针指向自己时为空队
next->
next==Q->
(3)入队
voidEnQueue(LinkQueue*Q,Datatypex)
//也就是在尾结点处插入元素
QueueNode*p=(QueueNode*)malloc(sizeof(QueueNode));
//申请新结点p->
data=x;
p->
next=Q->
//初始化新结点并链入Q-rear->
next=p;
rear=p;
//将尾指针移至新结点
DatatypeDeQueue(LinkQueue*Q)
{//出队,把头结点之后的元素摘下
Datatypet;
QueueNode*p;
if(EmptyQueue(Q))
Queueunderflow"
p=Q->
//p指向将要摘下的结点x=p->
data;
//保存结点中数据if(p==Q->
rear)
{//当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点Q->
Q->
next=p->
}else
//摘下结点pfree(p);
//释放被删结点returnx;
3.14对于循环向量中的循环队列,写出求队列长度的公式。
公式如下(设采用第二种方法,front指向真正的队首元素,rear指向真正队尾后一位置,向量空间大小:
QueueSize
Queuelen=(QueueSize+rear-front)%QueueSize
3.15假设循环队列中只设rear和quelen来分别指示队尾元素的位置和队中元素的个数,试给出判别此循环队列的队满条件,并写出相应的入队和出队算法,要求出队时需返回队头元素。
根据题意,可定义该循环队列的存储结构:
intquelen;
DatatypeData[QueueSize];
CirQueue*Q;
循环队列的队满条件是:
quelen==QueueSize知道了尾指针和元素个数,当然就能计算出队头元素的位置。
(1)判断队满
{//判队满,队中元素个数等于空间大小
quelen==QueueSize;
(2)入队
voidEnQueue(CirQueue*Q,Datatypex)
{//入队
if(FullQueue(Q))
队已满,无法入队"
//在循环意义上的加1Q->
quelen++;
(3)出队
DatatypeDeQueue(CirQueue*Q)
{//出队if(Q->
quelen==0)Error("
队已空,无元素可出队"
inttmpfront;
//设一个临时队头指针
tmpfront=(QueueSize+Q->
rear-Q->
quelen+1)%QueueSize;
//计算头指针位置Q->
quelen--;
Data[tmpfront];
如有侵权请联系告知删除,感谢你们的配合!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第三 队列 习题 答案