所謂排序,就是要整理檔案中的記錄,使之按關鍵字遞增(或遞減)次序排列起來。當待排序記錄的關鍵字都不相同時,排序結果是惟一的,否則排序結果不惟一。
在待排序的檔案中,若存在多個關鍵字相同的記錄,經過排序後這些具有相同關鍵字的記錄之間的相對次序保持不變,該排序方法是穩定的;若具有相同關鍵字的記錄之間的相對次序發生改變,則稱這種排序方法是不穩定的。
要注意的是,排序演算法的穩定性是針對所有輸入例項而言的。即在所有可能的輸入例項中,只要有乙個例項使得演算法不滿足穩定性要求,則該排序演算法就是不穩定的。
一.插入排序
插入排序的基本思想是每步將乙個待排序的記錄按其排序碼值的大小,插到前面已經排好的檔案中的適當位置,直到全部插入完為止。插入排序方法主要有直接插入排序和希爾排序。
①.直接插入排序(穩定)
接插入排序的過程為:在插入第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 0)
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) //直接選擇排序
}quick_sort(a,low,l-1);
quick_sort(a,l+1,high);}}
四.歸併排序
歸併排序是將兩個或兩個以上的有序子表合併成乙個新的有序表。初始時,把含有n個結點的待排序序列看作由n個長度都為1的有序子表組成,將它們依次兩兩歸併得到長度為2的若干有序子表,再對它們兩兩合併。直到得到長度為n的有序表,排序結束。
歸併排序是一種穩定的排序,可用順序儲存結構,也易於在鍊錶上實現,對長度為n的檔案,需進行log2n趟二路歸併,每趟歸併的時間為o(n),故其時間複雜度無論是在最好情況下還是在最壞情況下均是o(nlog2n)。歸併排序需要乙個輔助向量來暫存兩個有序子檔案歸併的結果,故其輔助空間複雜度為o(n),顯然它不是就地排序。
**略...
五.基數排序
設單關鍵字的每個分量的取值範圍均是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)的排序方法:快速排序、堆排序或
歸併排序。
快速排序是目前基於比較的內部排序中被認為是最好的方法,當待排序的關鍵字是隨機分布時,快速排序的平均時間最短;
堆排序所需的輔助空間少於快速排序,並且不會出現快速排序可能出現的最壞情況。這兩種排序都是不穩定的。
若要求排序穩定,則可選用歸併排序。但從單個記錄起進行兩兩歸併的 排序演算法並不值得提倡,通常可以將它和直接插入排序結合在一起使用。先利用直接插入排序求得較長的有序子檔案,然後再兩兩歸併之。因為直接插入排序是穩定的,所以改進後的歸併排序仍是穩定的。
常見排序的思想和實現
所謂排序,就是要整理檔案中的記錄,使之按關鍵字遞增 或遞減 次序排列起來。當待排序記錄的關鍵字都不相同時,排序結果是惟一的,否則排序結果不惟一。在待排序的檔案中,若存在多個關鍵字相同的記錄,經過排序後這些具有相同關鍵字的記錄之間的相對次序保持不變,該排序方法是穩定的 若具有相同關鍵字的記錄之間的相對...
常見排序演算法思想
穩定的排序演算法有 1.氣泡排序 將小的數往前挪,將大的數往後挪。2.插入排序 移動第i 1的那個數,在此數之前的序列中,從後往前進行比較相鄰的兩個數,將更小的數放前面,保證每次第i 1個之前的子串行有序。3.歸併排序 利用分治的思想,將乙個無序的陣列分解若干以兩個數為一組的子陣列,然後將每個子陣列...
常見排序的實現
這是相當簡單的排序方式,在具體實現的時候會有不同,具體有以下的兩個實現 實現1 void insert sort int arr,int length for k i 1 k j k arr j tmp 實現2,推薦使用 最差為o n 2 最好為o 1 演算法穩定 完全有序為o n void ins...