算法导论10-1
读书笔记
本小节介绍了栈和队列,其实总结起来就两句话:
- 栈:先入后出
- 队列:先入先出
但是在介绍队列的时候,讲到了一种如同衔尾蛇一样的定长队列,和apache的CircularFifoQueue实现是一致的。
课后习题
10.1-1
仿照图\(10-1\),画图表示一次执行操作\(PUSH(S,4)\)、\(PUSH(S,1)\)、\(PUSH(S,3)\)、\(POP(S)\)、\(PUSH(S,8)\)和\(POP(S)\)每一步的结果,栈\(S\)初始为空,存储于数组\(S[1..6]\)中。
略。
10.1-2
说明如何在一个数组\(A[1..n]\)中实现两个栈,使得当两个栈的元素个数之和不为\(n\)时,两者都不会上溢。要求\(PUSH\)和\(POP\)操作的运行时间为\(O(1)\)。
分别将数组的头和尾作为两个栈的栈底。
10.1-3
仿照图\(10-2\),画图表示依次执行操作\(ENQUEUE(Q,4)\)、\(ENQUEUE(Q,1)\)、\(ENQUEUE(Q,3)\)、\(DEQUEUE(Q)\)、\(ENQUEUE(Q,8)\)和\(DEQUEUE(Q)\)每一步的结果,初始队列为空,存储于数组\(Q[1..6]\)中。
略。
10.1-4
重写\(ENQUEUE\)和\(DEQUEUE\)的代码,使之能处理队列的下溢和上溢。
ENQUEUE(Q,x)
if Q.tail == Q.length
error 'overflow'
else
Q[Q.tail] = x
Q.tail = Q.tail + 1
DEQUEUE(Q)
if Q.tail == 1
error 'underflow'
else
x = Q[Q.head]
Q.head = Q.head + 1
return x
10.1-5
栈插入和删除元素只能在同一端进行,队列的插入操作和删除操作分别在两端进行,与它们不同,有一种双端队列,其插入和删除操作都可以在双端进行。写出\(4\)个时间均为\(O(1)\)的过程,分别实现在双端队列的两端插入和删除元素的操作,该队列是用一个数组实现的。
和上面的队列代码较为相似,只是现在数组的首尾都可以进行操作,溢出判断稍微复杂一点。
10.1-6
说明如何用两个栈实现一个队列,并分析相关队列的运行时间。
栈和队列的不同在于弹出元素的位置不同。
栈: 栈顶出栈;队列:队首出队;所以只需要把栈底元素之上的所有元素依次出栈,然后在另一个栈入栈;
添加元素应该是一样的为\(O(1)\);
弹出元素为\(O(n)\);
10.1-7
说明如何用两个队列实现一个栈,并分析相关栈操作的运行时间。
和上题相似,将一个队列里的元素倒腾到另一个队列中。
时间复杂度也是一样的。