《數據結構與算法分析:C語言描述_原書第二版》CH2算法分析_課后習題_部分解答


對於一個初學者來說,作者的Solutions Manual把太多的細節留給了讀者,這里盡自己的努力給出部分習題的詳解:

不當之處,歡迎指正。

1、  按增長率排列下列函數:N,2,N1.5,N2,NlogN, NloglogN,Nlog2N,Nlog(N2),2/N,2N,2N/2,37,N2logN,N3。指出哪些函數以相同的增長率增長。

   答:排列如下2/N < 37 < √2 < N < NloglogN < NlogN < Nlog(N2) < Nlog2N < N1.5 < N2 < N2logN < N3 < 2N/2 < 2N

   其中,NlogN 與 Nlog(N2) 的增長率相同,均為O(NlogN)。

   補充說明:a) 其中 Nlog2N 與 N1.5, N3 與 2N/2大小關系的判定,可以連續使用洛必達法則(N->∞時,兩個函數比值的極限,等於它們分別求導后比值的極限)。當然,更簡單的是兩邊直接求平方。

        b) 同時注意一個常用法則:對任意常數k,logkN = O(N)。這表明對數增長得非常緩慢。習題3中我們會證明它的一個更嚴格的形式。


2、  函數NlogN 與 N1+ε/√logN (ε>0) 哪個增長得更快?

   分析:我們首先考慮的可能是利用洛必達法則,但是對於第二個函數其上下兩部分皆含有變量,難以求導(當然也不是不行,就是麻煩些,如果你願意設y = N1+ε/√logN ,然后對兩邊取對數的話)。這里我們將利用反證法:

   要證NlogN < N1+ε/√logN ,即證 logN < Nε/√logN。既然用反證法,那么我們假設 Nε/√logN < logN。兩邊取對數有 ε/√logN logN < loglogN。即 ε√logN < loglogN。設t = logN,則 ε√t < logt <=> ε2t < log2t,這顯然與連續1中b)矛盾,因此假設 Nε/√logN < logN 不成立。因此函數 N1+ε/√logN增長得更快。


3、  證明對任意常數k,logkN = o(N)。

   解:要證明命題成立,只需證limn->∞(logkN / N) = 0即可。證明如下:

   首先,如果k1 < k2,顯然有 logk1N = o(logk2N) 。且k = 0時,logkn = 1。應用洛必達法則,limn->∞(logiN / N) = limn->∞(ilogi-1N / Nln2) = limn->∞(logi-1N / N) 。(說明:這里舍棄常數是因為我們假設函數最終的比值為0,否則不可簡單的丟棄常數。當然如果比值不為零的話,我們需要返回到這里另行處理,其實證明過程也是不斷嘗試、調整的,此路不通,另行它法嘛:)就是說,通過不斷地規約,最終極限的比值等於零,命題得證。


 4、 求兩個函數 f(N) 和 g(N),使得 f(N) ≠ O(g(N)) 且 g(N) ≠ O(f(N))。

   一個顯然的例子是函數 f(N) = sinN,g(N) = cosN。


 5、 假設需要生成前N個自然數的一個隨機置換。例如,{4,3,1,5,2} 和 {3,1,4,2,5} 就是合法的置換,但 {5,4,1,2,1} 卻不是,因為數1出現兩次而數3卻沒有出現。這個程序常常用於模擬一些算法。我們假設存在一個隨機數生成器 RandInt(i, j),它以相同的概率生成 i 和 j 之間的一個整數。下面是三個算法:

   1) 如下填入從 A[0] 到 A[N-1] 的數組 A:為了填入 A[i],生成隨機數直到它不同於已經生成的 A[0],A[1],... ,A[i-1],再將其填入 A[i]。

   2) 同算法1),但是要保存一個附加的數組,稱之為 Used(用過的)數組。當一個隨機數 Ran 最初被放入數組 A 的時候,置 Used[Ran] = 1。這就是說,當用一個隨機數填入 A[i] 時,可以用一步來測試是否該隨機數已經被使用,而不是像的一個算法那樣(可能)進行 i 步測試。

   3) 填寫該數組使得 A[i] = i + 1。然后:

   for(i = 1; i < N; i++)
     Swap(&A[i], &A[RandInt(0, i)]);

   對每一個算法給出你能夠得到的盡可能准確的期望的運行時間分析(用大O)。

   解:分析,對於1),容易寫出如下算法:

 for(i = 0; i < N; i++){
      while(1){
	  A[i] = RandInt(1, N);
	  for(j = 0; j < i; j++)
		if(A[j] == A[i])
		  break;
	  if(j == i)
		break;
        }
 }

   調用一次隨機數字生成函數與前面已經生成的隨機數(存放在A數組中的)不同的概率為 (N-i) / N,那么理論上經過 N / (N-i) 次隨機數的生成我們可以確定其與已生成的概率為 1。因此該算法的期望運行時間為

當然,也可以對分子放大的同時對分母縮小,不過這樣求得的時間界限為O(N2),顯然不如上面的做法精確。這里需要注意的一點是調和級數的前N項和,它是發散的,在計算機科學中的使用頻率要遠比在在數學等其它科目中使用得多。下面給出調和和:

其近似誤差r = 0.5772156649,這個值稱為歐拉常數(Euler’s constant)。

   對於2),容易寫出如下算法: 

for(i = 0; i < N; i++){
	while(1){
		A[i] = RandInt(1, N);
		if(Used[i] == 0){
			Used[i] = 1;
			break;
		}
	}
}

   同1)的分析,其運行時間界限顯然為O(NlogN)。

   對於3),運行時間為O(N),不消多說。


6、  記錄一個稱為Horner法則的算法,該算法用於計算 F(X) = Σi=0~nAiXi的值。

Poly = 0;
for(i = N; i >= 0; i--)
	Poly = X * Ploy + A[i];

 7、  給出一個有效的算法來確定在整數 A1  < A2 < A3 < ... < AN 的數組中是否存在整數 i ,使得 Ai = i。你的算法的運行時間是多少?

    分析:類似二分查找,直接上代碼:

int(int[] a, int N){
	int low = 0, high = N - 1, middle;
	
	while(low <= high){
		middle = ((high-low) >> 1) + low;
		
		if(a[middle]) < middle + 1)
			low = middle + 1;  // 搜索右空間
		else if(a[middle] > middle + 1)
			high = middle - 1; // 搜索左空間
		else 
			return middle;		
	}
	
	return -1;	
}

    易知該算法的運行時間為O(logN)。


 8、  如果7題中的語句 low = middle + 1 更該為 low = middle ,那么這個程序還能正確運行嗎?

    答:不能,設 low = n,high = n + 1,則 middle = n,程序陷入死循環。


 9、  a.編寫一個程序來確定正整數N是否是素數,你的程序在最壞的情形下的運行時間是多少(用N表示)?(你應該能夠寫出O(√N)的算法程序)。

    b.令B等於N的二進制表示法中的位數。B的值是多少?

    c.你的程序在最壞情形下的運行時間是什么(用B表示)?

    d.比較確定一個20(二進制)位的數是否是素數和確定一個40(二進制)位的數是否是素數的運行時間。

    e.用 N 還是 B 來給出運行時間更合理,為什么?

    解:對於a,由於 √N * √N = N,因此分解 N 時必有一個整數小於 √N。高效的算法思路是:首先,測試N是否能被2整除,不能的話測試N是否能被3,5,7,...,√N整除。編碼如下(是素數返回1,不是返回0): 

int IsPrime(int N){
	int i;
	
	if(N == 1)
		return 0;
	if(N % 2 == 0)
		return 0;
		
	for(i = 3; i <= int(sqrt(w) + 0.5); i += 2)
		if(N % i == 0)
			return 0;
			
	return 1;	
}

    對於b,顯然有,B = O(logN)。

    對於c,由於B = O(logN),則2B = O(N),即2B/2 = O(√N),所以用B表示的最壞情況下的運行時間是:O(2B/2)

    對於d,后者的運行時間是前者運行時間的平方,由c中的解答易知。

    對於e,Wiss說:B is the better measure because it more accurately represents the size of the input.


 

All Rights Reserved.
Author:海峰:)
Copyright © xp_jiang. 
轉載請標明出處:http://www.cnblogs.com/xpjiang/p/4143743.html

 參考資料:Data Structures and Algorithm Analysis in C(second edition) Solutions Manual_Mark Allen Weiss_Florida International University.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM