数据库系统l试题库及答案第3章栈与队列文档格式.docx
《数据库系统l试题库及答案第3章栈与队列文档格式.docx》由会员分享,可在线阅读,更多相关《数据库系统l试题库及答案第3章栈与队列文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
这时,第一次出栈得到的元素是A,第二次出栈得到的元素是B
经操作后,最后在栈中的元素还有_C个。
供选择的答案:
A〜B:
①a1②a2③a3④a4C:
①1②2③3④0
9.()从供选择的答案中,选出应填入下面叙述?
的对应栏内。
在做进栈运算时,应先判别栈是否_A_;
在做退栈运算时,应先判别栈是否_B—。
当栈中元
素为n个,做进栈运算时发生上溢,则说明该栈的最大容量为_C_。
为了增加内存空间的利用率和减少溢出的可能性,由两个栈共享一片连续的内存空间时,应将两栈的
D分别设在这片内存空间的两端,
这样,只有当
E时,才产生上溢。
A,B:
①空
②满
③上溢
④下溢
C:
①n-1
②n
③n+1
④n/2
D:
①长度
②深度
③栈顶
④栈底
E:
①两个栈的栈顶同时到达栈空间的中心点②其中一个栈的栈顶到达栈空间的中心点
③两个栈的栈顶在达栈空间的某一位置相遇④两个栈均不空,且一个栈的栈顶到达另一个栈的
栈底
10.设n个元素进栈序列是1,2,3,…,n,其输出序列是p1,p2,…,pn,若p仁3,则p2的值()。
A.一定是2B.一定是1C.不可能是1D.以上都不对
11.表达式a*(b+c)-d的后缀表达式是()。
A.abcd*+-B.abc+*d-C.abc*+d-D.-+*abcd
三、简答题
1•设有编号为1,2,3,4的四辆列车,顺序进入一个栈式结构的车站,具体写出这四辆列车开出车站的所有可能的顺序。
2.写出下列程序段的输出结果(栈的元素类型SEIemType为char)。
voidmain(){
StackS;
Charx,y;
InitStack(S);
X='
c'
;
y='
k'
;
Push(S,x);
Push(S,Pop(S,x);
Push(S,
'
Pash(S,y);
t'
);
s'
);
while(!
StackEmpty(S)){Pop(S,y);
printf(y);
};
Printf(x);
}
五、算法设计题
1.假设一个算术表达式中包含圆括弧、方括弧和花括弧三种类型的括弧,编写一个判别表达式中括弧是否正确配对的函数correct(exp,tag);
其中:
exp为字符串类型的变量(可理解为每个字符占用一个数组元素),表示被判别的表达式,tag为布尔型变量。
2.试写一个算法判别读入的一个以’@为结束符的字符序列是否是“回文”。
3.假设表达式有单字母变量和双目四则运算算符构成,试写一个算符,将一个通常书写形式切书写正确的表达式转换成逆波兰式(即后缀表达式)。
4.如上题的假设条件,试写一个算法,对以逆波兰式表示的表达式求值。
5.用一个一维数组S(设大小为maxsize)作为两个栈的共享空间。
请说明共享方法,栈满和栈空的判断
条件,并设计初始化栈InitStack(st)、进栈Push(st,i,x)和出栈Pop(st,i,x)等算法,其中i为0表示
第一个栈,i为1表示第二个栈。
3.2队列
一、填空题
1.队列只能在插入和删除元素。
是被限定为只能在表的一端进行插入运算,在表的另
一端进行删除运算的线性表。
2.在具有n个单元的循环队列中,队满时共有个元素。
3.循环队列的引入,目的是为了克服。
4.
1.
2.
3.
队列的特点是
、选择题
为解决计算机主机与打印机之间的速度不匹配问题,通常设计一个打印数据缓冲区,主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。
该缓冲区的逻辑结构应该是
A.
(
C.
)°
栈B.队列C
)不允许对队列进行的操作有(
对队列中的元素遍历B
在队列第一个元素之前插入元素
•图
)若用一个大小为6的数组来实现循环队列,且当前
.在队尾插入元素
.删除队头元素
rear禾口front
列中删除一个元素,再加入两个元素后,rear和front的值分别为(
A.1和5B.2和4C.4和2D.5和1()数组Q[n]用来表示一个循环队列,f为当前队列头元素的位置,位置,假定队列中元素的个数小于n,计算队列中元素的公式为()
的值分别为0和3,当从队
r为尾元素的位置的下一个
A.r—fB.(n+f—r)%nC.n
5.()从供选择的答案中,选出应填入下面叙述对应栏内。
内的最确切的解答,把相应编号写在答卷的
设有4个数据元素a1、a2、a3和a4,对他们分别进行队操作。
在进队操作时,按a1、a2、a3、
假设队的初始状态都是空。
考虑对这四个数据元素进行的队操作是进队两
次,出队一次,再进队两次,出队一次;
这时,第一次出队得到的元素是_A,第二次出队得到
的元素是_B。
经操作后,最后在栈中或队中的元素还有个。
①a1②a2③a3④a4
C:
6.
rear+仁frontD.(rear-l)MODn=front
()最大容量为n的循环队列,队尾是rear,队头是front,则队空的条件是()°
A.(rear+1)MODn=frontB.rear=frontC
A.(rear+1)MODn=frontB.rear=frontC.(rear-l)MODn=frontD.rear=(front+1)MODn
8.()栈和队列的共同点是()°
A.都是先进后出B.都是先进先出C.只允许在端点处插入和删除D.没有共同点
9.()最适合做链式队列的链表是()°
A.带队首指针和队尾指针的循环单链表B.带队首指针和队尾指针的非循环单链表
C.只带队首指针的非循环单链表D.只带队尾指针的循环单链表
三、判断题
1.()无论是循环队列还是链式队列,插入和删除运算的时间复杂度都是0
(1)°
2.()对于不同的使用者,一个表结构既可以是栈,也可以是队列,也可以是线性表。
3.()栈和队列是一种非线性数据结构。
4.()栈和队列的存储方式既可是顺序方式,也可是链接方式。
5.()队是一种插入与删除操作分别在表的两端进行的线性表,是一种先进后出型结构。
6.()通常使用队列来处理函数或过程的调用。
7.()栈和队列都是线性表,只是在插入和删除时受到了一些限制。
8.()队列用于操作系统中的作业调度。
四、简答题
1.设循环队列的容量为40(序号从0到39),现经过一系列的入队和出队运算后,有
①front=11,rear=19;
②front=19,rear=11;
问在这两种情况下,循环队列中各有元素多少个?
2•顺序队的“假溢出”是怎样产生的?
如何知道循环队列是空还是满?
五、阅读理解
1.写出下列程序段的输出结果(队列中的元素类型QEIemType为char)。
QueueQ;
InitQueue(Q);
Charx='
e'
c'
EnQueue(Q,'
h'
EnQueue(Q,En'
Queue»
;
(Q,y);
DeQueue(Q,x);
EnQueue(Q,x);
EnQueue(Q,'
a'
QueueEmpty(Q)){DeQueue(Q,y);
}
2.简述以下算法的功能(栈和队列的元素类型均为int)。
voidalgo3(Queue&
Q){
intd;
QueueEmpty(Q)){
DeQueue(Q,d);
Push(S,d);
};
StackEmpty(S)){
Pop(S,d);
EnQueue(Q,d);
六、算法设计题
1.假设以带头结点的循环链单表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。
—、填空题
线性任何栈顶表尾表头2.栈顶栈底3.存入元素移动栈顶指针4.移动栈顶指
1.StatusAIIBrackets_Test(char*str)〃判别表达式中三种括号是否匹配{
InitStack(s);
for(p=str;
*p;
p++)
{
if(*P=='
('
ll*P==TII*P=='
{'
)push(s,*p);
elseif(*p=='
)'
||*p=='
]'
}'
)
{if(StackEmpty(s))returnERROR;
pop(s,c);
if(*p=='
&
c!
='
)returnERROR;
if(*p==T&
['
//必须与当前栈顶括号匹配}
}//for
if(!
StackEmpty(s))returnERROR;
returnOK;
}//AIIBrackets_Test
2.intPalindrome_Test(){//判别输入的字符串是否回文序列,是则返回1,否则返回0
lnitQueue(Q);
while((c=getchar())!
@'
c=getchar())!
'
){
Push(S,c);
EnQueue(Q,c);
//同时使用栈和队列两种结构
StackEmpty(S))
Pop(S,a);
DeQueue(Q,b));
if(a!
=b)returnERROR;
}//Palindrome_Test
3.voidtrans(char*exp,charpostexp[])
//将算术表达式exp转换成后缀表达式postexp
{inti=0;
〃i作为postexp的下标
InitStack(op);
//op为运算符栈
Push(op,'
〃将'
进栈
while(*exp!
\0'
)//exp表达式未扫描完时循环
if(!
InOp(*exp))//为数字字符的情况
{postexp[i++]=*exp;
exp++;
else〃为运算符的情况
switch(Precede(op.data[op.top],*exp))〃判断优先级
case-1:
//栈顶运算符的优先级低:
Push(op,*exp);
//继续扫描其他字符
break;
case0:
//只有括号满足这种情况
Pop(op,e);
〃将(退栈
case1:
//退栈并输出到postexp中
postexp[i++]=e;
GetTop(op,e);
while(e!
)//此时exp扫描完毕,退栈到'
为止
postexp[i]='
\0:
〃给postexp表达式添加结束标识
4.floatcompvalue(char*postexp)//计算后缀表达式的值
{OPNDStackOPND;
//定义数值栈
InitStack_OPND(OPND);
floatd,a,b,c,e;
while(*postexp!
=‘\0'
)//postexp字符串未扫描完时循环{switch(*postexp){
case'
+'
:
//判定为'
号
Pop_OPND(OPND,a);
〃退栈取数值a
Pop_OPND(OPND,b);
〃退栈取数值b
c=a+b;
//计算c
Push_OPND(OPND,c);
〃将计算结果进栈break;
-'
〃退栈取数值aPop_OPND(OPND,b);
〃退栈取数值bc=b-a;
〃将计算结果进栈
*'
c=a*b;
〃计算c
/'
〃退栈取数值bif(a!
=0)
c=b/a;
else
printf("
\n\t除零错误!
\n"
exit(O);
〃异常退出
default:
〃处理数字字符
Push_OPND(OPND,postexp++);
GetTop_OPND(OPND,e);
return(e);
5•定义数据结构:
typedefstruct{
chardata[maxsize];
inttop1,top2;
}Stack;
voidInitStack(Stack&
S){
S.top1=0;
S.top2=maxsize-1;
intPush(Stack&
S,inti,ElemTypee){
if((S.top1+1)==S.top2)returnERRROR;
//栈满了不能再进栈
if(i==0){〃进第1个栈
S.data[S.top1]=e;
S.top1++;
elseif(i==1)//进第2个栈
S.data[S.top2]=e;
S.top2--;
elsereturnERROR;
//输入的i有误
intPop((Stack&
S,inti,ElemType&
e){
if(((i==0)&
(S.top1==0))||((i==1)&
(S.top2==maxsize-1)))returnERROR;
//栈空,不能出栈
if(i==0){//从第1个栈出栈
S.topl--;
e=S.data[S.top1];
elseif(i==1){//从第2个栈出栈
S.top2++;
e=S.data[S.top2];
1.队尾队首2.队列3.n-14.队列的假溢出5.先进先出
二、选择题
1.B2.C3.B4.D
5.(1,2,2)
6.B7.A8.D
9.B
1.V2.V3.
X4.
V5.X6.
X7.V8
V
1.用队列长度计算公式
(N
+r—f)%N
①L=(40+19-11)
%40=8
②L=(40+11—
19)%40=32
2.一般的一维数组队列的尾指针已经到了数组的上界,不能再有入队操作,但其实数组中还有空位置,这就叫“假溢出”。
采用循环队列是解决假溢出的途径。
另外,解决队满队空的办法有三:
1设置一个布尔变量以区别队满还是队空;
2浪费一个元素的空间,用于区别队满还是队空。
3使用一个计数器记录队列中元素个数(即队列长度)。
我们常采用法②,即队头指针、队尾指针中有一个指向实元素,而另一个指向空闲元素。
判断循环队列队空标志是:
f=rear队满标志是:
f=(r+1)%N
1.输出为“char”。
2.该算法的功能是:
利用堆栈做辅助,将队列中的数据元素进行逆置。
1.typedefintElemType;
typedefstructQNode{
ElemTypedata;
QNode*next;
}QNode,*QPtr;
QPtrrear;
intsize;
}Queue;
StatuslnitQueue(Queue&
q){
Q.rear=(Qnode*)malloc(sizeof(QNode));
if(!
Q.rear)exit(OVERFLOW);
q.rear->
next=q.rear;
//空的循环链表
q.size=0;
StatusEnQueue(Queue&
q,ElemTypee){
QPtrp;
p=(Qnode*)malloc(sizeof(QNode));
p)returnexit(OVERFLOW);
p->
data=e;
//创建被插入结点p
next=q.rear->
next;
next=p;
q.rear=p;
//将p所指结点插入到q.rear的后面}
q.size++;
StatusDeQueue(Queue&
q,ElemType&
e){
if(q.size==O)returnFALSE;
p=q.rear->
next->
//p指向循环链表的第一个结点(即被删结点)e=p_>
data;
next=p->
//删除p所指结点
free(p);
q.size--;