練習
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迴圈到...