栈和队列-第3章-《数据结构题集》习题解析-严蔚敏吴伟民版
习题集解析部分
第3章 栈和队列
——《数据结构题集》-严蔚敏.吴伟民版
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
相关测试数据下载 链接☛ 数据包
本习题文档的存放目录:数据结构\▼配套习题解析\▼03 栈和队列
文档中源码的存放目录:数据结构\▼配套习题解析\▼03 栈和队列\▼习题测试文档-03
源码测试数据存放目录:数据结构\▼配套习题解析\▼03 栈和队列\▼习题测试文档-03\Data
一、基础知识题
3.1❶若按教科书3.1.1节中图3.1(b)所示铁道进行车厢调度(注意:两侧铁道均为单向行驶道),则请回答:
(1) 如果进站的车厢序列为123,则可能得到的出站车厢序列是什么?
(2) 如果进站的车厢序列为123456,则能否得到435612和135426的出站序列,并请说明为什么不能得到或者如何得到(即写出以‘S’表示进栈和以‘X’表示出栈的栈操作序列)。
3.2❶简述栈和线性表的差别。
3.3❷写出下列程序段的输出结果(栈的元素类型SElemType为char)。
void main()
{
Stack S;
char x, 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);
}
3.4❷简述以下算法的功能(栈的元素类型SElemType为int)。
(1)status algo1(Stack S)
{
int i, n, A[255];
n=0;
while(!StackEmpty(S))
{
n++; Pop(S, A[n]);
}
for(i=1; i<=n; i++)
Push(S, A[i]);
}
(2)status algo2(Stack S,int e)
{
Stack T; int d;
InitStack(T);
while(!StackEmpty(S))
{
Pop(S, d);
if(d!=e)
Push(T, d);
}
while(!StackEmpty(T))
{
Pop(T, d);
Push(S, d);
}
}
3.5❹假设以S和X分别表示入栈和出栈的操作,则初态和终态均为空栈的入栈和出栈的操作序列可以表示为仅由S和X组成的序列。称可以操作的序列为合法序列(例如,SXSX为合法序列,SXXS为非法序列)。试给出区分给定序列为合法序列或非法序列的一般准则,并证明:两个不同的合法(栈操作)序列(对同一输入序列)不可能得到相同的输出元素(注意:在此指的是元素实体,而不是值)序列。
3.6❹ 试证明:若借助栈由输入序列12…n得到的输出序列为p1p2…pn(它是输入序列的一个排列),则在输出序列中不可能出现这样的情形:存在着i<j<k使pj<pk<pi。
3.7❹按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,并仿照教科书3.2节例3-2的格式,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程:
A-B×C/D+E↑F
3.8❸试推导求解n阶梵塔问题至少要执行的move操作的次数。
3.9❸试将下列递推过程改写为递归过程。
void ditui(int n)
{
int i;
i = n;
while(i>1)
cout<<i--;
}
3.10❸试将下列递归过程改写为非递归过程。
void test(int &sum)
{
int x;
cin>>x;
if(x==0)
sum=0;
else
{
test(sum);
sum+=x;
}
cout<<sum;
}
3.11❸简述队列和堆栈这两种数据类型的相同点和差异处。
3.12❸写出以下程序段的输出结果(队列中的元素类型QElemType为char)。
void main()
{
Queue Q;
InitQueue(Q);
char x= ‘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<<y;
}
cout<<x;
}
3.13❷简述以下算法的功能(栈和队列的元素类型均为int)。
void algo3(Queue &Q)
{
Stack S;
int d;
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,用以分别指示设在数组两端的两个栈,并讨论按过程(正/误状态变量可设为变参)或函数设计这些操作算法各有什么有缺点。
3.16❷假设如题3.1所属火车调度站的入口处有n节硬席或软席车厢(分别以H和S表示)等待调度,试编写算法,输出对这n节车厢进行调度的操作(即入栈或出栈操作)序列,以使所有的软席车厢都被调整到硬席车厢之前。
3.17❸试写一个算法,识别一次读入的一个以@为结束符的字符序列是否为形如‘序列1&序列2’模式的字符序列。其中序列1和序列2中都不含字符‘&’,且序列2是序列1的逆序列。例如,‘a+b&b+a’是属该模式的字符序列,而‘1+3&3-1’则不是。
3.18❷试写一个判别表达式中开、闭括号是否配对出现的算法。
3.19❹假设一个算数表达式中可以包含三种符号:圆括号“(”和“)”、方括号“[”和“]”和花括号“{”和“}”,且这三种括号可按任意的次序嵌套使用(如:…[…{…}…[…]…]…[…]…(…)…)。编写判别给定表达式中所含括号是否正确配对出现的算法(已知表达式已存入数据元素为字符的顺序表中)。
3.20❸假设以二维数组g(1…m, 1…n)表示一个图像区域,g[i,j]表示该区域中点(i,j)所具颜色,其值为从0到k的整数。编写算法置换点(i0,j0)所在区域的颜色。约定和(i0,j0)同色的上、下、左、右的邻接点为同色区域的点。
3.21❸假设表达式有单字母变量(下面算法中将改为只有一位的数字)和双目四则运算符构成。试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰表达式。
3.22❸如题3.21的假设条件,试写一个算法,对以逆波兰式表示的表达式求值。
3.23❺如题3.21的假设条件,试写一个算法,判断给定的非空后缀表达式是否为正确的逆波兰表达式,如果是,则将它转化为波兰式。
3.24❸试编写如下定义的递归函数的递归算法,并根据算法画出求g(5,2)时栈的变化过程。
3.25❹试写出求递归函数F(n)的递归算法,并消除递归:
3.26❹求解*方根√A的迭代函数定义如下:
其中,p是A的*似*方根,e是结果允许误差。试写出相应的递归算法,并消除递归。
3.27❺已知Ackerman函数的定义如下:
(1) 写出递归算法;
(2) 写出非递归算法;
(3) 根据非递归算法,画出求akm(2,1)时栈的变化过程。
链队
3.28❷假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。
顺序队
3.29❸如果希望循环队列中的元素都能得到利用,则需设置一个标志域tag,并以tag的值为0和1来区分,尾指针和头指针值相同时的队列状态是“空”还是“满”。试编写与此结构相应的入队列和出队列的算法,并从时间和空间角度讨论设标志和不设标志这两种方法的使用范围(如当循环队列容量较小而队列中每个元素占的空间较多时,哪一种方法较好)。
3.30❷假设将循环队列定义为:以域变量rear和length分别指示循环队列中队尾元素的位置和内含元素的个数。试给出此循环队列的队满条件,并写出相应的入队列和出队列的算法(在出队列的算法中要返回队头元素)。
3.32❹试利用循环队列编写求k阶菲波那契序列中前n+1项的算法,要求满足fn≤max而fn+1≥max,其中max为某个约定的常数。(注意:本题所用循环队列的容量仅为k,则在算法执行结束时,留在循环队列中的元素应是所求k阶菲波那契序列中的最后k项)
3.31❸假设称正读和反读都相同的字符序列为“回文”,例如,‘abba’和‘abcba’是回文,‘abcde’和‘ababab’则不是回文。试写一个算法判别读入的一个以‘@’为结束符的字符序列是否是“回文”。
3.33❸在顺序存储结构上实现输出受限的双端循环队列的入列和出列(只允许队头出列)算法。设每个元素表示一个待处理的作业,元素值表示作业的预计时间。入队列采取简化的短作业优先原则,若一个新提交的作业的预计执行时间小于队头和队尾作业的*均时间,则插入在队头,否则插入在队尾。
3.34❸假设在如教科书3.4.1节中图3.9所示的铁道转轨网的输入端有n节车厢:硬座、硬卧和软卧(分别以P,H和S表示)等待调度,要求这三种车厢在输出端铁道上的排列次序为:硬座(P)在前,软卧(S)在中,硬卧(H)在后。试利用输出受限(只允许队头出列)的双端队列对这n节车厢进行调度,编写算法输出调度的操作序列:分别以字符‘E’和‘D’表示对双端队列的头端进行入队列和出队列的操作;以字符A表示对双端队列的尾端进行入队列的操作。