演算法導論第二章思考題

sscout發表於2018-08-05

2-1

a.  

∵  長度為k的陣列

∴ 時間複雜度為 Θ(k²)

∵ 共有n/k個陣列

∴ T(n)= n/k * Θ(k²)= Θ(nk)

b.

2^i = n/k

∴ i = lg(n/k)

∴ 共有 lg(n/k)+ 1層

∵ 每層合併陣列花費的時間為 Θ(n)

∴ 合併所有子陣列的時間為 Θ(nlg(n/k))

c.

∵ 要與原來歸併排序具有相同的執行時間

∴ nlg(n/k)+ nk = c*nlgn

∵  當k逐漸增大,lg(n/k)逐漸減小

∴ k最大為lgn,此時lg(n/lgn)被忽略

d.

選擇插入排序比合並排序快的最大的列表長度

2-2

a.

 A’中的元素全部來自於A中變換後的元素。

b.

迴圈不變式:每次迭代之前,A[j]=min{A[k] | j<=k<=n},並且子陣列A[j..n]中的元素還是最初在A[j..n]中的元素。

初始化:第一次迭代之前j=n,子陣列A[j..n]只包含一個元素A[n],迴圈不變式顯然成立。

保持:迭代一個給定值的j。首先假設此次迭代前迴圈不變式成立,那麼根據迴圈不變式,A[j]是A[j..n]中最小的元素。第3~4行程式碼表示如果A[j]<A[j-1]就交換A[j]和A[j-1],顯然這使得A[j-1]成為A[j-1..n]中最小的元素。由於唯一改變子陣列A[j-1..n]的操作僅僅是那次可能發生的交換操作,且在迭代開始時,A[j..n]中的元素最初都是在A[j..n]中,所以在迭代開始時A[j-1..n]中的元素最初都是在A[j-1..n]中。然後j自減,準備開始進入下一輪迭代。

終止:迴圈終止時j=i。根據迴圈不變式,A[j]=A[i]=min{A[k] | i<=k<=n},並且A[i..n]中的元素最初都在A[i..n]中。

所以在2~4行的for迴圈執行結束過後,A[i]將是A[i..n]中最小的元素。

c.

迴圈不變式:每次迭代之前,子陣列A[1..i-1]包含了A[1..n]中前i-1小的所有元素,並且它們是已排好序的。A[i..n]中包含了A[1..n]中餘暇的元素。

初始化:第一次迭代之前i=1。子陣列A[1..i-1]為空,迴圈不變式顯然成立。

保持:迭代一個給定值的i。首先假設此次迭代前迴圈不變式成立,那麼根據迴圈不變式,A[1..i-1]包含了A[1..n]中前i-1小的所有元素,並且它們是已排好序的。第一部分已經證明:在執行2~4行的for迴圈後A[i]是A[i..n]中最小的元素。所以在執行了2~4行的for迴圈後A[1..i]中就包含了A[1..n]中前i小的所有元素,並且它們已經排好序。子陣列A[i+1..n]就包含了n-i個A[1..n]中餘下的元素。

終止:迴圈終止時i=n+1 => i-1=n。所以根據迴圈不變式,A[1..i-1]óA[1..n]中包含了A[1..n]中前i-1小的元素(即A[1..n]的全部元素),並且它們是排好序的。

所以在1~4行的for迴圈執行結束過後,A[1..n]將是有序的。

根據第二部分的結論,外層for迴圈結束後,陣列A[1..n]中的元素將是排好序的。故氣泡排序演算法是正確的。

d.

最壞情況的執行時間是Θ(n²),效能比插入排序差,在以排好序的陣列中插入排序的執行時間是Θ(n),而氣泡排序仍是Θ(n²)。

2-3

a.

Θ(n)

b.

樸素的多項式程式碼實現

public static int test(int[] arr,int x) {
		int sum = 0;
		int v;
		
		for(int i = 0;i < arr.length;i++) {
			v = 1;
			for(int j = 0;j < i;j++) {
				v *= x; 
			}
			sum += v*arr[i];
		}
		
		return sum;
	}

執行時間是Θ(n²)

與霍納規則相比,效能差很多

c.

初始化:i = n,y = 0,當i代入迴圈不變式後y = 0,迴圈不變式成立

保持:

終止:i = -1,此時y = Σ(0,n)akx^k,與迴圈不變式當i = -1時的多項式y相等,即為所求之和

d.

歸納法,類似上面保持裡的方法,假設 i = 1成立,在乘以x得出結果與i=0比較即可

2-4

a.

(1,5)(2,5)(3,4)(3,5)(4,5)

b.

降序排列的陣列,有n(n-1)/2對逆序對

c.

逆序對的數量越多,插入排序的時間越長

證明:

在增序排列的陣列中,逆序對最少為0,此時插入排序的執行時間為Θ(n)

而當降序排列的陣列中,逆序對最多為n(n-1)/2,此時插入排序的執行時間為Θ(n²)

不難看出逆序對越多所造成的內層迴圈也就越多,執行時間也越長

d.

歸併排序過程中每次將兩個子序列歸併成一個子序列的過程中,如果左邊的元素大於右邊的元素,計數就自增,歸併完成後就是逆序對數目。

相關文章