以下问题已在 GATE CS 2006 考试中提出。
1. 队列 Q 的实现,使用两个堆栈 S1 和 S2,如下所示:
void insert(Q, x) {
push (S1, x);
}
void delete(Q){
if(stack-empty(S2)) then
if(stack-empty(S1)) then {
print(“Q is empty”);
return;
}
else while (!(stack-empty(S1))){
x=pop(S1);
push(S2,x);
}
x=pop(S2);
}
设 n 个插入和 m (<=n) 个删除操作在一个空队列 Q 上以任意顺序执行。设 x 和 y 是进程中分别执行的 push 和 pop 操作的数量。以下哪一项对所有 m 和 n 都是正确的?
(A) n+m <= x < 2n 和 2m <= y <= n+m (B) n+m <= x < 2n 和 2m<= y <= 2n (C) 2m <= x < 2n 和2m <= y <= n+m (D) 2m <= x <2n and 2m <= y <= 2n Answer(A) 插入和删除操作的执行顺序在这里很重要。最好的情况:插入和删除操作交替执行。在每次删除操作中,执行 2 次弹出和 1 次推送操作。因此,总共执行了 m+ n push(n push for insert() 和 m push for delete())操作和 2m pop 操作。
最坏的情况:首先插入 n 个元素,然后删除 m 个元素。在第一次删除操作中,进行了 n+1 次弹出操作和 n 次推送操作。除第一次外,在所有删除操作中,执行一次弹出操作。因此,总共执行了 m + n 个弹出操作和 2n 个推送操作(n push 用于 insert() 和 m push 用于 delete())
2. 考虑下图:
以下哪一项不能是使用 Kruskal 算法按该顺序添加到最小生成树的边序列?
(A) (a-b),(d-f),(b-f),(d-c),(d-e)
(B) (a-b),(d-f),(d-c),(b-f),(d-e)
(C) (d-f),(a-b),(d-c),(b-f),(d-e)
(D) (d-f),(a-b),(b-f),(d-e),(d-c)
答案 (D)
在 Kruskal 的最小生成树算法中,不能在 (dc) 之前考虑边 (de),因为 Kruskal 的算法在每一步都从当前边集中选择权重最小的边。
3. 可以在 O(n) 时间内找到 n 个元素的中位数。关于快速排序的复杂性,以下哪一项是正确的,选择哪个中位数作为主元?
(A) Θ(n)
(B) Θ(nlogn)
(C) Θ(n^2)
(D) Θ(n^3)
答案 (B)
如果中值始终用作主元,则对于所有 cn 是中值查找和分区的组合时间的情况,递归仍然是 T(n) = 2T(n/2) + cn。因此,这种快速排序的最坏情况时间复杂度变为 Θ(nlogn)。然而,在实际实现中,这个变体平均要慢得多(参见 http://en.wikipedia.org/wiki/Quicksort#Selection-based_pivoting)