演算法導論2 3 6參考

2021-08-26 20:22:20 字數 2489 閱讀 7151

按照題目描述,我們需要將插入排序中的5~7行,while迴圈實現的將「比a[i]大的數後移」的功能用二分查詢的思路進行優化。2.3-5也有提到優化思路,即插入排序每一次迴圈結束後前面的i個數已經完成從小到大的排序,只需要將目標值a[j]與前i個數的中間值a[i/2]比較,就能知道a[j]應該在的區間,並減少一半的判斷時間。

偽**://_(:зゝ∠)_

binary_insertion_sort ( a , l , r )//輸入a[0..n],0,n

if r > 2……………………………………………………c1

binary_insertion_sort ( a , l , r-1 )…………c2//r==2之前一直呼叫函式對前面的r-1個元素進行排序

key = a[ r ]………………………………………………c3//待插入的值給key

binary_insert ( a , l , r - 1 , key )………………c4//將a[ r ]插入前面已經排好的0~r-1序列中

//遞迴的插入排序主函式

binary_insert ( a , l , r , key )

if l > r……………………………………………………c5

a[ l] = key…………………………………………c6

return………………………………………………c7//若左溢位則將key賦給溢位之前的位置,若右溢位則賦值給l=r+1這個溢位位,即未排序的那個數的位置不動

else if key <= a[ ( l + r ) / 2]…………………………c8//若key值在二分點左側則要將二分點右側所有元素右移一位

for i = r downto ( l + r ) / 2……………………c9

a[ i + 1 ] = a [ i ]……………………………………c10

binary_insert ( a , l , ( l + r ) / 2 , key )……c11//繼續找key該呆的位置

else binary_insert ( a , ( l + r ) / 2 , r , key )…………c12//若key值在二分點右側則不做處理,繼續迭代

//二分比較並移動較大項函式

鑑於計算過程太繁雜,手碼的話要浪費大量時間,就直接給結果了_(:зゝ∠)_,其中k1~5都是用於替換c1~11組成的一次算式的常數。

binary_insertion_sort函式的遞迴式為:

t1( n ) = k4 + t1( n - 1 ) + t2( n ),n>=2.

binary_insert函式的遞迴式為:

t2 ( n ) = k1 * n + k2 + t2 ( n - 1 ),n>1

t2 ( 1 ) = k3,                                  n=1.

通式:(lg(n)代表以2為底,n的對數,書上有說明

t2( n ) = 2 * k1 * n + k2 * lg(n) - 2 * k1 +k3

t1( n ) = k1 * (n² + n - 2) + k2 * lg(n!) + k5 * ( n - 1 )//用斯特林公式將n!做近似處理,不懂的這裡

t1( n ) = k1 * n² + k2 * n *lg(n) + ( k1 - lg(e) *k2 + k5 ) *n +lg((2*π*n)½) -2 * k1 - k5

故將while替換後也不會對原插入排序的複雜度o(n²)造成多大影響,更不可能達到題目要求的o(n*lgn)。

但是這做法也做了對while的部分優化,優化了多少呢?有興趣的同學請看下面。

將k1~k5的值代入原式(自己拿草稿紙寫一下吧

k1= 0.5 * ( c9 + c10 + c11 )

k2= c5 + c8 + c9

k3= c5 + c6 + c7

k4= c1 + c2 + c3 + c4

k5= - k2 + k3 + k4

接下來將這篇裡的k1、k2的值也代入原式t(n)。(用書裡第14~15頁的**與t(n)的通式比較也行。

對比兩組**中的相似部分,本文中n²的係數k1中包含了c10(自減)、c11(換位)、c12(呼叫自己),而書中n²的係數包含了c5(比較大小、判斷是否溢位)、c6(換位)、c7(自減)。可見其中 自減 和 換位 兩項沒有被優化,而本文中的比較大小和判斷是否溢位分別是c8(比較大小)、c5(判斷是否溢位),他們分別屬於,c8->(k2,k5),c5->(k2,k3,k5)。如果我們忽略小值,那麼c8(比較大小)的時間複雜度為o(n*lgn),c5(判斷是否溢位)的時間複雜度為o(n)。

如果把比較大小和判斷是否溢位這兩個判斷語句拆開來算,那麼這個改動對原插入排序排序演算法的的優化點為,將「比較兩數大小」由o(n²)降低到o(n*lgn),將「判斷是否溢位」o(n²)降低到o(n),額外增添了「自己呼叫自己」複雜度為o(n²)。

全域性優化為o(n²)-o(n*lgn)-o(n)。不知道「自己呼叫自己」這步的具體時長與另外兩步有多大區別,好心前輩可以幫忙補充一下或指出我的錯誤,不然看起來好像還不如不優化_(:зゝ∠)_,謝謝大家,喜歡請點贊(>^ω^<)。

關於堆排序 參考自演算法導論

堆排序是一種很有用的排序演算法,有用的並不是在排序上的用處,而是那個大根堆和小根堆的建立,在平時的運用中,舉足輕重!乙個最有用的例項就是作業系統的程序的最大優先權排程演算法。從很多程序中,找到優先順序最大的程序,然後分配cpu資源。堆排序的主要步驟也就是建立堆。一旦最大堆 最小堆 建立好了,排序也是...

演算法導論 隨機演算法

一.概率分布 對於有些問題本身是屬於概率問題,如僱傭問題 對於此類問題,我們需要利用概率分析來得到演算法的執行時間,有時也用來分析其他的量。例如,僱傭問題中的費用問題也需要結合概率分析來計算得到。為了使用概率分析,我們必須使用或者假設已知關於輸入的概率分布,然後通過分析該演算法計算出平均情況下的執行...

《演算法導論》 演算法導論2 2 1插入排序

2.1 插入排序。我們分析的第乙個演算法是插入排序演算法,輸入 n個數 a1,a2,a3,a4,a5,a6,a7 an 輸出 序列的乙個排列 即重新排序 a1 a2 a3 使a1 a2 a3 插入排序演算法的偽 是以乙個過程的形式給出的,稱為insertion sort,它的引數是乙個陣列。包括了n...