2-1(在歸併排序中對最小數組採用插入排序) 雖然歸併排序的最壞情況運行時間爲θ(nlgn),而插入排序的最壞情況運行時間爲θ(n2 ),但是插入排序中的常量因子可能使得它在n較小時,在許多機器上實際運行得更快。因此,在歸併排序中當子問題變得足夠小時,採用插入排序來使遞歸的葉變粗是有意義的。考慮對歸併排序的一種修改,其中使用插入排序來排序長度爲k的n/k個子表,然後使用標準的合併機制來合併這些子表,這裏k是一個待定的值。
a) 證明:插入排序最壞情況可以在θ(nk)時間內排序每個長度爲k的n/k個子表
b) 表明在最壞情況下如何在θ(nlg(n/k))時間內合併這些子表
c) 假定修改後的算法的最壞情況運行時間爲θ(nk+nlg(n/k)),要使修改後的算法與標準的歸併排序具有相同的運行時間,作爲n的一個函數,藉助θ記號,k的最大值是什麼?
d) 在實踐中,我們應該如何選擇k?
a)
每張子表的排序時間爲(1+n/k)*k/2=k/2+n/2
k張表爲
b)
將內容兩兩合併,第一次合併是複雜度是θ(n),一共比較了lg(n/k)次,故最壞情況下複雜度是nlg(n/k)
c)
nk+nlg(n/k)=nlgn解方程即可
d)
很多因素影響k,比如,操作系統中的分頁機制,受內存來影響k。
2-2 (冒泡排序的正確性) 冒泡排序是一種流行但低效的排序方法,它的作用是反覆交換相鄰的未按次序排列的元素
BUBBLESORT(A)
for i=1 to A.length-1
for j=A.length downto i+1
if A[j]<A[j-1}
exchange A[j]with A[j-1]
a) 假設A’表示BUBBLESORT(A)的輸出。爲了證明BUBBLESORT正確,我們必須鍾明它將終止並且有:A’[1]<=A’[2]<=……<=A’[n],其中n=A.length。爲了證明BUBBLESORT確實完成了排序,我們還需要證明什麼?下面兩部分將證明不等式
b) 爲第2~4行的for循環精確地說明一個循環不變式,並證明該循環不變式成立。你的證明應該使用本章中給出的循環不變式證明的結構
c) 使用b部分的循環不變式的終止條件,爲第1~4行的for循環說明一個循環不變式,該不變式將使你能證明不等式2.3。你的證明應該使用本章中給出的循環不變式證明的結構。
d) 冒泡排序的最壞情況運行時間是多少?與插入排序的運行時間相比,其性能如何?
b)
循環不變式證明如下:
初始化:i=1,j=n,確保A[n-1]<A[n]
保持:將A[j-1]和A[j]比較,使得A[j-1]<A[j]
終止:當j=i+1時循環終止,因爲A[i]是已經排好的順序,此時有A[i+1]是已經排好的順序。
綜上所述,此算法正確。
c)
初始化:i=1時,內循環將找出A[1…n]中的最小值,並賦值給A[1]。A[1]僅有一個元素,故A[1]已有序。
保持:如果i=k時,A[1…k]已有序。
終止:當i=n-1時,有A’[1]<=A’[2]<=…<=A’[n-1],而A’[n-1]是A[n-1]與A[n]中較小者,故定有A’[n-1]<=A’[n],故1到n有序。
綜上所述,此算法正確。
d)
最壞時間是(1+n)n/2,插入排序是n^2,複雜度相同,均爲θ(
2-3 (霍納Horner規則的正確性)給定係數a0,a1,……,an 和x的值,代碼片段
y=0
for i=n downto 0
y=ai+x*y
實現了用於求值多項式
的霍納規則。
a)藉助θ記號,實現霍納規則的以上代碼片段的運行時間是多少?
b)編寫僞代碼來實現樸素的多項式求值算法,該算法從頭開始計算多項式的每個項。該算法的運行時間是多少?與霍納規則相比,其性能如何?
c)考慮一下循環不變式:在第2~3行for循環每次迭代的開始有
y=∑k=0n−(i+1)ak+i+1xk
把沒有項的和式解釋爲等於0。遵照本章中給出的循環不變式證明的結構,使用該循環不變式來證明終止時有y=∑nk=0akxk。
d)最後證明上面給出的代碼片段將正確地由係數a0,a1,……,an 刻畫的多項式的值。
a)
進行了n次運算,運行時間是θ(n)
b)
樸素多項式僞代碼:
y=0
for i=0 to n
y=y+ai*x^i
運行時間是θ(
霍納規則的性能更高。
c)
循環不變式證明如下:
初始化:i=0時,
保持:i=k時,
終止:i=n時,
綜上所述,此算法正確。
d)
這段代碼本質是一個遞歸。
2-4 (逆序時)假設A[1…n]是一個有n個不同數的數組。若i
a)列出數組(2,3,8,6,1)的5個逆序對。
b)由集合(1,2,…,n)中的元素構成的什麼數組具有最多的逆序對?它有多少逆序對?
c)插入排序的運行時間與輸入數組中逆序對的數量之間是什麼關係?證明你的回答。
d)給出一個確定在n個元素的任何排序中逆序對數量的算法,最壞情況需要θ(nlgn)時間(提示:修改歸併排序)
a)
(1,5)、(2,5)、(3,5)、(4,5)、(3,4)
b)
倒序的數組具有最多的逆序對
個數是:n*(n-1)/2個
c)
逆序數等於交換的次數
d)
由c)可知,逆序數等於交換的次數。這樣的話此題變成了複雜度爲θ(nlgn)的算法。算法如下:
1)採用了分治的思想,改寫了原先寫好的歸併/合併排序。
2)在每次“合併”的時候,分別拿出右側子序列中的元素,到左側子序列中比較來得出部分逆序數。
3)把三個部分的逆序數加在一起。