幾種常用排序演算法總結

2021-06-09 21:22:12 字數 3802 閱讀 9308

排序(強力推薦,這個算是總結的不錯的一篇文章,直接轉了)

文章中的**也許有些錯誤,關於直接插入排序,第一篇已經做出了修改,其他的有時間再看

所謂排序,就是要整理檔案中的記錄,使之按關鍵字遞增(或遞減)次序排列起來。當待排序記錄的關鍵字都不相同時,排序結果是惟一的,否則排序結果不惟一。

在待排序的檔案中,若存在多個關鍵字相同的記錄,經過排序後這些具有相同關鍵字的記錄之間的相對次序保持不變,該排序方法是穩定的;若具有相同關鍵字的記錄之間的相對次序發生改變,則稱這種排序方法是不穩定的。

要注意的是,排序演算法的穩定性是針對所有輸入例項而言的。即在所有可能的輸入例項中,只要有乙個例項使得演算法不滿足穩定性要求,則該排序演算法就是不穩定的。

一.插入排序

插入排序的基本思想是每步將乙個待排序的記錄按其排序碼值的大小,插到前面已經排好的檔案中的適當位置,直到全部插入完為止。插入排序方法主要有直接插入排序和希爾排序。

①.直接插入排序(穩定)

接插入排序的過程為:在插入第i個記錄時,r1,r2,..ri-1已經排好序,將第i個記錄的排序碼ki依次和r1,r2,..,ri-1的排序碼逐個進行比較,找到適當的位置。使用直接插入排序,對於具有n個記錄的檔案,要進行n-1趟排序。

**如下:

void dir_insert(int a,int n)  //直接插入排序

a[j+1]=t;}

}②.希爾排序(不穩定):

希爾(shell)排序的基本思想是:先取乙個小於n的整數d1作為第乙個增量把檔案的全部記錄分成d1個組。所有距離為d1的倍數的記錄放在同乙個組中。先在各組內進行直接插入排序;然後,取得第二個增量d2

希爾排序是不穩定的,希爾排序的執行時間依賴於增量序列,其平均時間複雜度為o(n^1.3).

**如下:

void shell(int a,int n)  //shell排序

a[i+k]=t;

}if(k == 1) break;

(k/2)%2 ==0 ? k=k/2+1 : k=k/2;}

}二.選擇排序

選擇排序的基本思想是每步從待排序的記錄中選出排序碼最小的記錄,順序存放在已排序的記錄序列的後面,直到全部排完。選擇排序中主要使用直接選擇排序和堆排序。  

①.直接選擇排序(不穩定)

直接選擇排序的過程是:首先在所有記錄中選出序碼最小的記錄,把它與第1個記錄交換,然後在其餘的記錄內選出排序碼最小的記錄,與第2個記錄交換......依次類推,直到所有記錄排完為止。

無**件初始狀態如何,在第i趟排序中選出最小關鍵字的記錄,需要做n-i次比較,因此,總的比較次數為n(n-1)/2=o(n^2)。當初始檔案為正序時,移動次數為0;檔案初態為反序時,每趟排序均要執行交換操作,總的移動次數取最大值3(n-1)。直接選擇排序的平均時間複雜度為o(n^2)。直接選擇排序是不穩定的。

**如下:

void dir_choose(int a,int n)  //直接選擇排序

②.堆排序(不穩定)

堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。n個關鍵字序列

k1,k2,...,kn稱為堆,當且僅當該序列滿足(ki<=k2i且ki<=k2i+1)或(ki>=k2i且ki>=k2i+1),(1<=i<=n/2)。根結點(堆頂)的關鍵字是堆裡所有結點關鍵字中最小者,稱為小根堆;根結點的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆。

若將此序列所儲存的向量r[1..n]看作是一棵完全二叉樹的儲存結構,則堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。

堆排序的關鍵步驟有兩個:一是如何建立初始堆;二是當堆的根結點與堆的最後乙個結點交換後,如何對少了乙個結點後的結點序列做調整,使之重新成為堆。堆排序的最壞時間複雜度為o(nlog2n),堆排序的平均效能較接近於最壞效能。由於建初始堆所需的比較 次數較多,所以堆排序不適宜於記錄較少的檔案。堆排序是就地排序,輔助空間為o(1),它是不穩定的排序方法。

**如下:(原文中沒有,我自己在網上找的)

// array是待調整的堆

陣列,i是待調整的陣列元素的位置,nlength是陣列的長度

void heapadjust(int array,int i,int nlength)//本函式功能是:根據陣列array構建大根堆

else // 否則退出迴圈

break;// 最後把需要調整的元素值放到合適的位置

array[nchild]= ntemp; }

}// 堆排序演算法

void heapsort(int array,int length)

// 從最後乙個元素開始對序列進行調整,不斷的縮小調整的範圍直到第乙個元素

for (int i = length - 1; i > 0; --i) }

} 三.交換排序

交換排序的基本思想是:兩兩比較待排序記錄的排序碼,並交換不滿足順序要求的那寫偶對,直到滿足條件為止。交換排序的主要方法有氣泡排序和快速排序.

while(i<=mid) b[k++]=a[i++];

while(j<=high) b[k++]=a[j++];

for(i=low;i<=high;i++)

a[i]=b[i]; }

void gui(int a,int b)

} 五.基數排序

設單關鍵字的每個分量的取值範圍均是c0<=kj<=crd-1(0<=j<=rd),可能的取值個數rd稱為基數.基數的選擇和關鍵字的分解因關鍵字的型別而異.

(1).若關鍵字是十進位制整數,則按個、十等位進行分解,基數rd=10,c0=0,c9=9,d為最長整數的位數.

(2).若關鍵字是小寫的英文本串,則rd=26,c0='a',c25='z',d為最長字串的長度.

基數排序的基本思想是:從低位到高位依次對待排序的關鍵碼進行分配和收集,經過d趟分配和收集,就可以得到乙個有序序列.

按平均時間將排序分為四類:

(1)平方階(o(n2))排序

一般稱為簡單排序,例如直接插入、直接選擇和氣泡排序;

(2)線性對數階(o(nlgn))排序

如快速、堆和歸併排序;

(3)o(n1+£)階排序

£是介於0和1之間的常數,即0<£<1,如希爾排序;

(4)線性階(o(n))排序

如基數排序。

各種排序方法比較

簡單排序中直接插入最好,快速排序最快,當檔案為正序時,直接插入和冒泡均最佳。

影響排序效果的因素

因為不同的排序方法適應不同的應用環境和要求,所以選擇合適的排序方法應綜合考慮下列因素:

①待排序的記錄數目n;

②記錄的大小(規模);

③關鍵字的結構及其初始狀態;

④對穩定性的要求;

⑤語言工具的條件;

⑥儲存結構;

⑦時間和輔助空間複雜度等。

不同條件下,排序方法的選擇

(1)若n較小(如n≤50),可採用直接插入或直接選擇排序。

當記錄規模較小時,直接插入排序較好;否則因為直接選擇移動的記錄數少於直接插人,應選直接選擇排序為宜。

(2)若檔案初始狀態基本有序(指正序),則應選用直接插人、冒泡或隨機的快速排序為宜;

(3)若n較大,則應採用時間複雜度為o(nlgn)的排序方法:快速排序、堆排序或歸併排序。

快速排序是目前基於比較的內部排序中被認為是最好的方法,當待排序的關鍵字是隨機分布時,快速排序的平均時間最短;堆排序所需的輔助空間少於快速排序,並且不會出現快速排序可能出現的最壞情況。這兩種排序都是不穩定的。

若要求排序穩定,則可選用歸併排序。但從單個記錄起進行兩兩歸併的  排序演算法並不值得提倡,通常可以將它和直接插入排序結合在一起使用。先利用直接插入排序求得較長的有序子檔案,然後再兩兩歸併之。因為直接插入排序是穩定的,所以改進後的歸併排序仍是穩定的。

幾種常用排序演算法總結

所謂排序,就是要整理檔案中的記錄,使之按關鍵字遞增 或遞減 次序排列起來。當待排序記錄的關鍵字都不相同時,排序結果是惟一的,否則排序結果不惟一。在待排序的檔案中,若存在多個關鍵字相同的記錄,經過排序後這些具有相同關鍵字的記錄之間的相對次序保持不變,該排序方法是穩定的 若具有相同關鍵字的記錄之間的相對...

幾種常用排序演算法

一 氣泡排序 已知一組無序資料a 1 a 2 a n 需將其按公升序排列。首先比較a 1 與a 2 的值,若a 1 大於a 2 則交換兩者的值,否則不變。再比較a 2 與a 3 的值,若a 2 大於a 3 則交換兩者的值,否則不變。再比較a 3 與a 4 依此類推,最後比較a n 1 與a n 的值...

常用幾種排序演算法

常用的幾種排序演算法 選擇排序方法時,除了基本實現的要求外,還應當注重所選擇演算法的時間 空間複雜度既執行效率,另外在實際工作中往往還要注意演算法的穩定性 排序後相同元素的相對位置是否發生改變 等。一 冒泡 插入 選擇 二 快排 歸併 1 氣泡排序 氣泡排序只會操作相鄰的兩個資料。每次冒泡操作都會對...