8.2-2 證明COUNTING-SORT是穩定的。
問題解答:
假設輸入數組A[1...n],length[A]=n,數組A中有兩個元素具有相同的值,下標分別為a,b(1≤a<b≤n)即A[a] = A[b]。經過計數排序運行至行7,C[A[a]] = C[A[b]]。在第9~11行中循環部分中,循環變量 i 用於指示數組A的下標,其值從 length[A] 到 1 遞減遍歷。由b>a可知,A[b]優先插入數組B中。在循環執行體行10、行11中,每當將一個值A[i]放入數組B位置C[A[i]]時,都要使C[A[i]]的值減1。因此,A[b]首先插入數組輸出數組B中,且A[a]插入在A[b]的前一個位置上。
8.2-3 在COUNTING-SORT過程中,假設第9中for循環的首部改成改寫成如下形式
9
for j ← 1 to length[A]
證明該算法仍能正常的工作。修改后的算法是穩定的嗎?
問題解答:
在第9~11行中循環部分中,循環變量i用於指示輸入數組A的下標。循環首部的改變,僅改變數組A中元素遍歷次序,即數組A中元素插入數組B的次序,從
大下標優先插入變為
小下標優先插入。數組A中元素插入數組B的位置為C[A[i]],只和元素的值有關,和元素的下標無關。所以修改后的算法仍然能正常的工作。
修改后的算法,數組A中元素插入數組B的次序是
小下標優先插入。如果有兩個元素有相同的值,即指向C中同一個元素,則較小下標的元素優先插入數組B中,然后使指向的C中元素減1,所以較大下標的元素插入到較小下標的元素的前面。算法是不穩定的。
8.3-2 下面的算法中那些是穩定的:插入排序,合並排序,堆排序和快速排序?給出一個能是任何排序算法都穩定的方法。給出的方法帶來的額外時空開銷是多少?
問題解答:
插入排序、合並排序均是穩定的;快速排序,堆排序不穩定。
先給每個元素增加一個域index,表示在輸入數組中的索引值。元素之間的比較,先比較元素的值,若值是相等的話,需進一步比較index。每個index可用
lg
n位大小的整數來表示,需額外的
Ω
(
n
lg
n
)空間。由於增加的額外的比較次數至多和原先的比較次數相同,時間復雜度並不變。(參考答案)
8.3-4說明如何在O(n)時間內,對0到n^2-1之間的n個整數進行排序。
問題解答:
引理8.3 給定n個d位數,每一個數位可以取k種可能的值。如果所用的穩定排序需要Θ(n+k)的時間,基數排序算法能以Θ(d(n+k))的時間正確地對這些數進行排序。
若采用n進制對0到n^2-1之間的數表示,需要2位數即可。由上述引理可得,基數排序的時間為Θ(d(n+k))=Θ(2(n+n)) =Θ(n) (參考答案)
8.4-2 桶排序的最壞情況運行時間是什么?如果要在保持其線性運行時間的同時,使最壞情況時間為O(nlgn),要對算法做什么樣的修改?
問題解答:
最壞情況下,即所有的輸入元素均落入一個桶內,桶排序就退化為一個插入排序。而插入排序的最壞情況時間代價為Θ(n^2)。如果要在保持其線性運行時間的同時,使最壞情況時間為O(nlgn),對桶內元素排序方法更換為最壞情況為O(nlgn)的合並排序。
8.4-3在單位圓內有n個點,pi=(xi, yi),使得0<xi^2 + yi^2 ≤1, i = 1,2,....,n。假設所有點是均勻分布的,亦即,某點落在圓的任一區域中的概率與該區域的面積成正比。請設計一個Θ(n)期望的算法,來根據點到原點的距離di=sqrt(xi^2 + yi^2)對n個點排序。
問題解答:
桶排序是把區間[0,1)區間划分成n個大小相同的子區間(即桶),且要求輸入元素等可能落在任何桶中。按照桶排序的思想,把單位圓划分成n個等面積的同心環即可。
設:輸入元素有兩個域x,y,分別表示橫坐標和縱坐標。元素之間的大小比較是通過比較di=sqrt(xi^2 + yi^2)來判斷的。
算法偽代碼:
BUCKET-SORT'(A)
n ← length(A)
for i ←1 to n
do index ← floor( n( A[i].x^2 + A[i].y^2 ) )
insert A[i] into B[index]
for i ←1 to n
do sort list B[i] with insertion sort
concatenate the list B[0], B[1], ..., B[n-1] together in order
思考題
8-2
以線性時間原地排序
假設有一個有n個數據記錄組成的數組要排序,且每個記錄的關鍵字的值為0或1。排序這樣一組記錄的一個算法應具備如下三個特性中的一部分。
1)算法的運行時間為O(n)。
2)算法是穩定的。
3)算法是原地排序的,它可以使用除輸入數組以外的固定量的存儲空間。
a)給出一個滿足上述條件1和條件2的算法。
b)給出一個滿足上述條件1和條件3的算法。
c)給出一個滿足上述條件2和條件3的算法。
d)在a)~c)中給出的算法能否用來在O(bn)時間內排序,對有b位關鍵字的n個記錄進行基數排序?如果行,說明如何做;如果不行,說明原因。
e)假設一個n個記錄中每個的關鍵字都介於1到k之間。說明如何修改計數排序,使得可以在O(n+k)時間內對n個記錄原地排序。除輸入數組外,可另用O(k)的存儲空間。你給出算法是穩定的嗎?(提示:當k=3時應該如何做)
問題解答:
a)使用計數排序即可滿足要求。
b)由於記錄的關鍵字的值只有兩種情況(0或1),可使用類似快速排序中PARTITION將數組划分為兩個區域,一區域只含關鍵字值均為0,另一區域關鍵字均為1。
具體算法為:
PARTITON-SORT(A)
n ← lenght[A]
i ← 1
while A[i] = 0 and i ≤ n
do i ← i + 1
p← i
i ← i - 1
for j ← p to n
do if A[j] = 0
then i ← i + 1
exchange A[i] ↔ A[j]
c) 使用插入排序或合並排序即可滿足要求
d)
a)算法可以,對數組元素的每一位的排序都采用計數排序即可。
b)算法不可以,是由於快速排序算法的數組分割是不穩定的。
c)算法也不可以,是由於插入排序和合並排序的最壞運行時間為O(n^2)。
e) 說明暫時不會