希爾排序,堆排序,歸併排序

2021-09-28 23:28:04 字數 1233 閱讀 4122

思想:

(1)在直接插入排序的思想上,如果先使陣列盡可能有序,則就可使時間複雜度趨近o(n)。因此,演算法也集中在使陣列有序。首先用分組的方法將陣列分組,這裡舉例假設陣列有11個數,我們可以分為3個為1組,再1個為1組。

(2)給定乙個陣列分組的寬度,則外層迴圈就可直接從i=0+width開始,並用tmp儲存當前arr[i]的值,然後i++向後直到遍歷完陣列;內層迴圈j需要從外層迴圈當前小組中的左鄰第乙個開始倒退,每次走width個長度,即j-=width,每次都需要與tmp計較,如果tmp小於arr[j],則將arr[j]賦給arr[j+width],然後j倒退;否則直接使跳出本次內層迴圈,內層迴圈結束後將tmp的值賦給arr[j+width]。然後進入下一次外層迴圈。

時間複雜度:o(n ^1.3~ n ^1.5)

空間複雜度:o(1)

穩定性:不穩定

思想:(1)將陣列模擬劃分為乙個完全二叉樹,此時我們可以得知完全二叉樹的特性:已知父節點或者左右子節點的任意乙個就可求出剩餘的兩個。比如:已知父節點為n,則左子節點為2n+1,右子節點為2n+2;已知左或右子節點為n,則父節點為(n-1)/2。

(2)堆排序,首先得構造最大堆,從當前葉子節點的根節點開始,使得父節點不能小於子節點。先用tmp儲存開始位置的值arr[start],外層迴圈i從start開始,i–倒退,直到i=0;內層迴圈j從當前start的左子節點開始,下一次迴圈每次到當前j的左子節點,並限制j在陣列長度-1範圍內。進入內層迴圈,首先判斷左子節點的值是否大於右子節點,如果小於則令j++保證j當前的值儲存子節點中的較大值。然後比較tmp與當前arr[j]的值,如果tmp>arr[j],則跳出本次內層迴圈,否則arr[start]=arr[j]並令start=j,內層迴圈條件結束後,令arr[start]=tmp;

(3)在構建最大堆的基礎上,從0開始,逐步遍歷需要迴圈len-1次,將當前樹的第乙個父節點與樹的最後乙個節點交換,然後再進行一次調整,即就是呼叫構建最大堆的內層迴圈。

時間複雜度:o(nlogn)

空間複雜度:o(1)

穩定性:不穩定

思想:( 1 )通過長度迴圈乘2的方式分組,在組內逐步找到較小的值賦給另乙個陣列,每次迴圈都可以保證各組內有序,從而下一次迴圈就相當於將小組內的右半組中的數有序的與左半組一同賦值給另乙個陣列,再由另乙個陣列傳給當前陣列。

( 2 )組內實現:分兩種情況

第一種:存在右半組;即就是low2第二種:只有左半組,即就是low1時間複雜度:o(nlogn)

空間複雜度:o(n)

穩定性:穩定

希爾排序 堆排序 歸併排序

希爾排序 by donald shell 利用了插入排序的簡單 同時克服 插入排序以此交換消去乙個 逆序對的困難.既然我們 決定 要 做上述之事 那麼我們 最迫切的事情就是 確定我們以此交換 間隔幾個位置?假定給了乙個需要排序的陣列並且 按照5 間隔的方式進行排序 附圖如下 我們 慢慢的按照 越來越...

幾種排序,希爾排序,快速排序,堆排序,歸併排序

因為最近看了一點stl,所以用vector代替了陣列,從別的地方借鑑了很多,只是簡單的實現,也沒有做什麼優化,其實也不會 include include includeusing namespace std void print vectorv swap v left v high quick so...

氣泡排序,插入排序,堆排序,歸併排序,希爾排序

感謝姥姥提供模板 感謝姥姥 展示 include include using namespace std 氣泡排序 void bubble sort int arr,int n 插入排序 void insertionsort int arr,int n arr i tmp 希爾排序 void she...