算法与数据结构 第三章 栈与队列(详解)

本文深入探讨了数据结构中的栈和队列,包括它们的定义、操作以及在实际问题中的应用。特别地,解释了如何使用栈来检查表达式的平衡括号,以及循环队列如何解决假溢出问题。此外,还讨论了递归算法的时间复杂度,以及如何通过非递归方式重写递归程序。同时,文章指出栈在函数调用中的关键作用,并强调了栈和队列在信息技术中的重要地位。
摘要由CSDN通过智能技术生成

目录

一、判断题

二、选择题 


一、判断题

1、所谓“循环队列”是指用单向循环链表或者循环数组表示的队列。F

解析:错误,循环队列指的是后者,用数组表示的队列,利用求余数运算使得头尾相接。循环队列本身是一种顺序存储结构,而循环链表是一种链式存储结构。

2、An algorithm to check for balancing symbols in an expression uses a stack to store the symbols.T

解析:balancing symbols指的是一组匹配的符号,类似于圆括号,花括号,方括号。可见这道题的意思是求解逆波兰表达式,使用stack。

3、可以通过少用一个存储空间的方法解决循环队列假溢出现象。F

解析:少用一个存储空间的方法是为了解决无法判别队列满还是空。
而克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。

4、循环队列执行出队操作时会引起大量元素的移动。F

解析:

5、两个栈共享一片连续空间,可以将两个栈的栈底分别设在这片空间的两端。T

解析:两个栈共享一片连续内存空间时,为提高内存利用率,减少溢出机会,应把两个栈的栈底分别设在这片内存空间的两端。

6、栈底元素是不能删除的元素。F

解析:我认为可以删除,只要栈中只有一个元素时,栈底元素和栈顶元素一样。

7、循环队列也存在着空间溢出问题。T

解析:循环队列解决的是“假溢出”问题,但是仍然出现真正的溢出。

8、"Circular Queue" is defined to be a queue implemented by a circularly linked list or a circular array.“循环队列”定义为由循环链表或循环数组实现的队列。F

解析:循环队列是一个抽象的概念,不局限于实现方式。 

二、选择题 

1、若用一个大小为6的数组来实现循环队列,且当前rear和fornt的值分别为0和3。从当前队列中删除一个元素,再加入两个元素后,rear和front的值分别为( )。

A.4和2

B.1和5

C.5和1

D.2和4

解析:当出队列中删除一个元素,也就是出队,即front+1=4再插入两个元素,即rear+2= 2。

2、若栈采用顺序存储方式存储,现两栈共享空间V[1..m],top[i]代表第i个栈( i =1,2)栈顶元素所在的下标,栈1的底在v[1],栈2的底在V[m],则栈满的条件是( )。

A.top[1]+1=top[2]

B.|top[2]-top[1]|=0

C.top[1]=top[2]

D.top[1]+top[2]=m

解析:当他们满的时候,两个指针相邻 那就是 top[1]+1=top[2]。

3、设有一个递归算法如下
        int fact(int n)
{  //n大于等于0
             if(n<=0) return 1;
             else return n * fact(n-1);
}
则计算fact(n)需要调用该函数的次数为( )。

A.n+1

B.n

C.n+2

D.n-1

解析:应该选A,循环n次从n减到1,需要再循环一次,减到0。 

4、假定利用数组a[n]顺序存储一个栈,用top表示栈顶指针,用top==-1表示栈空,并已知栈未满,当元素x进栈时所执行的操作为( )。

A.a[top--]=x

B.a[top++]=x

C.a[--top]=x

D.a[++top]=x

解析:入栈时,移动栈顶指针,将元素入栈。所以应该是++top,注意++top和top++的区别。 

5、循环队列的队满条件为 ( )。

A.(sq.rear+1) % maxsize ==sq.front

B.(sq.front+1) % maxsize ==sq.rear

C.(sq.rear+1) % maxsize ==(sq.front+1) % maxsize

D.sq.rear ==sq.front

解析:为了方便起见,约定:初始化建空队时,令front=rear=0,

  当队空时:front=rear

  当队满时:front=rear 亦成立

  因此只凭等式front=rear无法判断队空还是队满。  有两种方法处理上述问题:

    (1)另设一个标志位以区别队列是空还是满。

    (2)少用一个元素空间,约定以“队列头指针front在队尾指针rear的下一个位置上”作为队列“满”状态的标志。即:

  队空时: front=rear

  队满时: (rear+1)%maxsize=front

  front指向队首元素,rear指向队尾元素的下一个元素。

q->front==q->rear+1明显是一个判定条件,判定当前队列是否已满,当当前队列q->front正好为0,q->rear为(maxsize-1,即整个队列的最后一个),q->rear+1就溢出了,(q->rear+1)%maxsize正好就是0,从而可以判断front和rear+1是不是同一个位置。

6、下列关于栈的叙述中,错误的是:

  1. 采用非递归方式重写递归程序时必须使用栈
  2. 函数调用时,系统要用栈保存必要的信息
  3. 只要确定了入栈次序,即可确定出栈次序
  4. 栈是一种受限的线性表,允许在其两端进行操作

A.仅 2、3、4

B.仅 1、3、4

C.仅 1

D.仅 1、2、3

解析:A非递归一般情况下不需要栈的。因为递归是一定需要栈的,而非递归若要用递归的算法完成算法,就要使用人工的栈而不是系统栈。如果采用别的算法,就可以不使用栈了。

B比如说,我在函数A中还要调用其他函数,那么这个时候先要把函数A一些变量的信息记录下来,就是存在栈中,然后再调用新的函数(也可以是自身)。等A调用的函数运行完获得返回值时,会回到最初调用它的函数(也就是A),这个时候函数A可能还要继续运行,也可能直接就return了,无论哪种情况都需要把之前存在栈中的信息pop出来,否则一调用其他函数,A自己原先的变量数据就无法跟踪记录了。

7、下列说法中,正确的是( )。

A.通常使用队列来处理函数或过程调用

B.消除递归不一定需要使用栈

C.队列和栈都是运算受限的线性表,只允许在表的两端进行运算

D.对同一输入序列进行两组不同的合法入栈和出栈组合操作,所得的输出序列也一定相同

解析:应该选B

A错,通常使用堆栈来处理函数或过程调用。

D错可以push和pop间隔进行,也可以先进行完push然后再进行pop,即使输入序列相同,输出也不相同。

8、若采用带头、尾指针的单向链表表示一个堆栈,那么该堆栈的栈顶指针top应该如何设置?

A.将链表尾设为top

B.随便哪端作为top都可以

C.链表头、尾都不适合作为top

D.将链表头设为to

解析:这里头尾指针是链表的,和栈没关系,即头指针不等于栈底,尾指针不等于栈顶。出入栈都是对栈顶元素进行的操作,考虑到这个链表是单向的(只能从前往后,不能从后往前),所以把头指针设成top,这样出入栈都是对表头进行的操作,节约时间。

也可以理解为,top在尾部无法判空,而表头为top可以根据指针是否为空判断栈是否为空。

上面的题目均是博主在期末考试前总结的重难点,欢迎各位大佬指正错误或者给出更优质的解析。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值