《演算法導論》習題答案 第二章

2022-06-25 02:36:10 字數 3088 閱讀 8661

練習

2.1-2

將第5行判斷a[ i ] > key -->   a[ i ] < key

2.1-3

algorithm 1 linear-search( a, v )

輸入 :陣列a = < a1, a2, ..., an > 和值 v

輸出:使得a[ i ] == v 的下標, 若v不在a內輸出 nil 

for i = 1 to n 

if a[ i ] == v

return i

return nil

迴圈不變式: a[1, 2, ..., i-1 ]中沒有值等於v 。 

2.1-4

形式化描述(?) 模擬手算,二進位制從低位到高位依次儲存(大端(big-endian),便於進製)。

algorithm 2 binary-addition(a, b, n)

輸入:兩個整數 a, b 與它們的二進位制位數n

輸出:a+b的二進位制

let a[ 1...n ], b[ 1...n ] and c[ 1...n+1 ] to be new arrays

for i = 1 to n

a[ i ] = a&1

b[ i ] = b&1

a>>=1

b>>=1

for i = 1 to n

c[ i+1 ] = (c[ i ] +  a[ i ] + b[ i ] ) / 2 //進製

c[ i ]    = ( a[ i ] + b[ i ] ) %2 //當前位

2.2-1

n^3/1000 - 100n^2 - 100n + 3 = o( n^3 ) (暫時用o表示書中的theta 忽略係數,只取最高項)

2.2-2

假設函式find-min(a, r, s) 返回陣列a下標從r到s的元素最小值的下標, 函式執行時間為o( s- r ) ( r<=s ) 

algorithm 3 selection-sort( a )

輸入:陣列a

輸出:順序排列的a

for i in 1 to n-1

j = find-min( a, i, n )

a[ i ] <---> a[ j ]  //交換元素a[i]與a[j]

迴圈不變式: a[ 1, 2, ..., i-1 ] 已經排列完畢並且a陣列其餘元素都大於等於迴圈不變式中的元素

因為最後剩下的元素a[ n ] 一定是最大的,所以只需要排列n-1次

時間複雜度: for迴圈n-1次,find-min時間複雜度o( n ) 所以總體時間複雜度為 o(∑i(1<=i<=n)) = o( n^2 ) 這個複雜度同時符合(holds)最好情況和最壞情況

2.2-3

因為每個元素都有可能是要查詢的元素,所以查詢元素有1/2可能在陣列前一半,同時有一半可能在陣列後一半,平均下來需要查詢一半的元素。

最壞情況即要查詢的元素在最後乙個,即要查詢n次。 最好和最壞情況時間複雜度都為o( n )

2.2-4 

其中乙個方法是針對最好情況修改演算法,使其有效的處理最好情況。

2.3-4

遞迴版本的插入排序:

algorithm 4 insertion-sort( a , n )

輸入:陣列a

輸出:順序排列的a

if n>1 

insertion-sort( n-1 )

key = a[ n ]

i = n-1

while i>0 && a[ i ] > key

a[ i+1 ] = a[ i ]

i = i-1

a[ i+1 ] = key 

t( n ) = t( n-1 ) + o( n ) = o(∑i(1<=i<=n)) = o( n^2 ) 

2.3-5

遞迴版二分搜尋:

binary-search( a, l, r, v)

輸入 :陣列a = < a1, a2, ..., an > 和值 v

輸出:使得a[ i ] == v 的下標, 若v不在a內輸出 nil 

if lm = ( l + r ) / 2

if a[m] ==v 

return m

if a[m] < v 

binary-search(a, m+1, r, v)

else

binary-search(a, l, m-1, v)

return nil

因為長度n最多二分lgn次,所以二分查詢最壞情況為o(lgn)

2.3-6

如果用二分搜尋,其目標應該是返回第乙個大於v的下標。二分的變形總結  時間複雜度為o(lgn)

但找到下標後還需要讓所有之後的元素後移乙個位置,時間複雜度為o(n),所以最壞執行時間為o(∑i(1<=i<=n-1)) = o( n^2 ) 

2.3-7

思路1:先用時間複雜度<=o( nlgn )的排序演算法排序陣列s(如歸併排序),如果有a+b==x 則 a = x-b , 可以在s中用二分查詢是否有值為x-s[ i ] (1<=i<=s.length ) t(n)=o(nlgn)+o(nlgn) = o(nlgn)

思路2:先排序,從兩端到中間查詢是否有s[ i ] + s[ j ] == x (1<=ialgorithm 5 check-sum( s, x )

輸入:陣列s及數值x

輸出:若s中有兩個元素和為x,返回true , 否則false

merge-sort( s )

n  = s.length

for i = 1 to n

if binary-search( s, 1, n, x-a[ i ])   //參見2.3-2

return true

return false

merge-sort( s )

n  = s.length

i = 1

j = n

while( iif s[ i ] + s[ j ] == x

return true

elseif  s[ i ] + s[ j ]  > x

j = j - 1

else

i = i + 1

return false

思考題2.1

演算法導論課後習題第二章(1)

練習 2.1 1 以圖 2 2 為模型,說明 insertion sort 在陣列 a 31,41,59,26,41,58 上的 執行過程。2.1 2 重寫過程 insertion sort,使之按非公升序 而丌是按非降序 排序。insertion sort a 1 for j 2 to lengt...

演算法導論第二章

插入排序原始碼 1 include 2 include 3 4using namespace std 56 void insert sort inta 7 17 a i 1 key 18 19 2021 intmain 22view code 逆序輸出 1 include 2 include 3 4...

演算法導論 第二章作業

作業2.1 2 template void insert t a,int n a i 1 key 2.1 3 template void find t a,int n,t v if i 1 v nil 迴圈不變式 初始化 i 1,v還沒和任何a陣列中的元素比較,所以是 1,它為真。保持 如果j迴圈到...