日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构中的各种排序---总结篇

發布時間:2024/1/23 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构中的各种排序---总结篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:http://blog.csdn.net/wzyhb123456789/article/details/5974790

一個月沒有寫文章,原因是一直在忙碌著,但是其實是有收獲的,下面就是我這前半個月最大的收獲:對于數據結構中排序算法的總結,在我找工作的道路上幫助了我好多。如有錯誤,歡迎指正!

?

?

一、基本概念:

1、??排序:按照一定的關鍵字,將一個序列排列成想要得到的一個新的序列。

2、??內部排序和外部排序:整個排序過程完全在內存中進行,叫做內部排序。數據量較大需要借助外部存儲設備才能完成,叫做外部排序。

3、??主關鍵字和此關鍵字:

4、??排序的穩定性:對于相同的元素來說,在排序之前和之后的書訊是一樣的,那么這種排序就是穩定的排序,如果順序發生了變化,那么就是不穩定排序。

二、插入類排序:

(一)???思想:在一個已經排好序的序列中,將未被排進的元素按照原先的規定插入到指定位置。

(二)???分類:

1、??直接插入排序:

①???思想:最基本的插入排序,將第i個插入到前i-1個中的適當位置。

②???時間復雜度:T(n) = O(n2)

③???空間復雜度:S(n) = O(1)

④???穩定性:穩定排序。循環條件while(r[0].key < r[j].key)保證的。

⑤???程序:

[cpp]?view plaincopy
  • void?InsSort(RecordType?r[],?int?length)??
  • {??
  • ????for(i?=?2;?I?<=?length;?i++)??
  • ????{??
  • ????????r[0]?=?r[i];??
  • ????????j?=?i?–?1;??
  • ????????while(r[0].key?<?r[j].key)??
  • ????????{??
  • ????????????r[j?+?1]?=?r[j];?j?=?j?–?1;??
  • ????????}??
  • ????????r[j+1]?=?r[0];??
  • ????}??
  • }??
  • 2、??折半插入排序:

    ①???思想:因為是已經確定了前部分是有序序列,所以在查找插入位置的時候可以用折半查找的方法進行查找,提高效率。

    ②???時間復雜度:比較時的時間減為O(nn),但是移動元素的時間耗費未變,所以總是得時間復雜度還是O(n2)

    ③???空間復雜度:S(n) = O(1)

    ④???穩定性:穩定排序。

    ⑤???程序:

    [cpp]?view plaincopy
  • void?BinSort(RecordType?r[],?int?length)??
  • {??
  • ????for(i?=?2;?i?<=?length;?i++)??
  • ????{??
  • ????????x?=?r[i];??
  • ????????low?=?1;?high?=?i?–?1;??
  • ????????while(low?<=?high)??
  • ????????{??
  • ????????????mid?=?(low?+?high)?/?2;??
  • ????????????if(x.key?<?r[mid].key)??
  • ????????????????high?=?mid?–?1;??
  • ????????????else??
  • ????????????????low?=?mid?–?1;??
  • ????????}??
  • ????????for(j?=?i?–?1;?j?>=?low;?--j)??
  • ????????????r[j?+?1]?=?r[j];??
  • ????????r[low]?=?x;??
  • ????}??
  • }??
  • 3、??希爾排序:

    ①???思想:又稱縮小增量排序法。把待排序序列分成若干較小的子序列,然后逐個使用直接插入排序法排序,最后再對一個較為有序的序列進行一次排序,主要是為了減少移動的次數,提高效率。原理應該就是從無序到漸漸有序,要比直接從無序到有序移動的次數會少一些。

    ②???時間復雜度:O(n1.5次方)

    ③???空間復雜度:O(1)

    ④???穩定性:不穩定排序。{2,4,1,2}21一組42一組,進行希爾排序,第一個2和最后一個2會發生位置上的變化。

    ⑤???程序:

    [cpp]?view plaincopy
  • void?ShellInsert(RecordType?r[],?int?length,?int?delta)??
  • {??
  • ????for(i?=?1?+?delta;?i?<=?length;?i++)/*1+delta為第一個子序列的第二個元素的下表*/??
  • ????if(r[i].key?<?r[1?-?delta].key)??
  • ????{??
  • ????????r[0]?=?r[i];??
  • ????????for(j?=?i?–?delta;?j?>?0?&&?r[0].key?<?r[j].key;?j?-=delta)??
  • ????????????r[j?+?delta]?=?r[j];??
  • ????????r[j?+?delta]?=?r[0];??
  • ????}??
  • }??
  • void?ShellSort(RecordType?r[],?int?length,?int?delta[],?int?n)??
  • {??
  • ????for(i?=?0;?i?<=?n?–?1;?++i)??
  • ????????ShellInsert(r,?length,?delta[i]);??
  • }??
  • 三、交換類排序:

    (一)???思想:通過交換逆序元素進行排序的方法。

    (二)???分類:

    1、??冒泡排序:

    ①???思想:反復掃描待排序序列,在掃描的過程中順次比較相鄰的兩個元素的大小,若逆序就交換位置。第一趟,從第一個數據開始,比較相鄰的兩個數據,(以升序為例)如果大就交換,得到一個最大數據在末尾;然后進行第二趟,只掃描前n-1個元素,得到次大的放在倒數第二位。以此類推,最后得到升序序列。如果在掃描過程中,發現沒有交換,說明已經排好序列,直接終止掃描。所以最多進行n-1趟掃描。

    ②???時間復雜度:T(n) = O(n2)

    ③???空間復雜度:S(n) = O(1)

    ④???穩定性:穩定排序。

    ⑤???程序:

    [cpp]?view plaincopy
  • void?BubbleSort(RecordType?r[],?int?length)??
  • {??
  • ????n?=?length;??
  • ????change?=?TRUE;??
  • ????for(i?=?1;?i?<=?n?–?1?&&?change;?i++)??
  • ????{??
  • ????????change?=?FALSE;??
  • ????????for(j?=?1;?j?<=?n?–?I;?++j)??
  • ????????????if(r[j].key?>?r[j?+?1].key)??
  • ????????????{??
  • ????????????????x?=?r[j];??
  • ????????????????r[j]?=?r[j?+?1];??
  • ????????????????r[j?+?1]?=?x;??
  • ????????????????change?=?TRUE;??
  • ?????????????}??
  • ????}??
  • }??
  • 2、??快速排序:

    ①???思想:冒泡排序一次只能消除一個逆序,為了能一次消除多個逆序,采用快速排序。以一個關鍵字為軸,從左從右依次與其進行對比,然后交換,第一趟結束后,可以把序列分為兩個子序列,然后再分段進行快速排序,達到高效。

    ②???時間復雜度:平均T(n) = O(nn),最壞O(n2)

    ③???空間復雜度:S(n) = O(n)

    ④???穩定性:不穩定排序。{3?2?2}

    ⑤???程序:

    [cpp]?view plaincopy
  • void?QKSort(RecordType?r[],?int?low,?int?high)??
  • {??
  • ????int?pos;??
  • ????if(low?<?high)??
  • ????{??
  • ????????pos?=?QKPass(r,?low,?high);??
  • ????????QKSort(r,?low,?pos?-?1);??
  • ????????QKSort(r,?pos?+?1,?high);??
  • ????}??
  • }??
  • int?QKPass(RecordType?r[],?int?left,?int?right)??
  • {??
  • ????RecordType?x;??
  • ????int?low,?high;??
  • ????x?=?r[left];??
  • ????low?=?left;??
  • ????high?=?right;??
  • ????while(low?<?high)??
  • ????{??
  • ????????while(low?<?high?&&?r[high].key?>=?x.key)??
  • ????????????high--;??
  • ????????if(low?<?high)??
  • ????????{??
  • ????????????r[low]?=?r[high];??
  • ????????????low++;??
  • ????????}??
  • ????????while(low?<?high?&&?r[low].key?<?x.key)??
  • ????????????low++;??
  • ????????if(low?<?high)??
  • ????????{??
  • ????????????r[high]?=?r[low];??
  • ????????????high--;??
  • ????????}??
  • ????}??
  • ????r[low]?=?x;??
  • ????return?low;??
  • }??
  • 四、選擇類排序:

    (一)???思想:每一趟在n – i + 1 ( i = 1,2,??, n - 1)個記錄中選取關鍵字最小的記錄作為有序序列中的第i個記錄。

    (二)???分類:

    1、??簡單選擇排序:

    ①???思想:第一趟時,從第一個記錄開始,通過n – 1次關鍵字的比較,從n個記錄中選出關鍵字最小的記錄,并和第一個記錄進行交換。第二趟從第二個記錄開始,選擇最小的和第二個記錄交換。以此類推,直至全部排序完畢。

    ②???時間復雜度:T(n) = O(n2)

    ③???空間復雜度:S(n) = O(1)

    ④???穩定性:不穩定排序,{3?3?2}

    ⑤???程序:

    [cpp]?view plaincopy
  • void?SelectSort(RecordType?r[],?int?length)??
  • {??
  • ????n?=?length;??
  • ????for(i?=?1;?i?<=?n?-?1;?i++)??
  • ????{??
  • ????????k?=?i;??
  • ????????for(j?=?i?+?1;?j?<=?n;?i++)??
  • ????????if(r[j].key?<?r[k],key)??
  • ????????????k?=?j;??
  • ????????????if(k?!=?i)??
  • ????????????{??
  • ????????????????x?=?r[i];??
  • ????????????????r[i]?=?r[k];??
  • ????????????????r[k]?=?x;??
  • ????????????}??
  • ????}??
  • }??
  • 2、??樹形選擇排序:

    ①???思想:為了減少比較次數,兩兩進行比較,得出的較小的值再兩兩比較,直至得出最小的輸出,然后在原來位置上置為∞,再進行比較。直至所有都輸出。

    ②???時間復雜度:T(n) = O(nn)

    ③???空間復雜度:較簡單選擇排序,增加了n-1個額外的存儲空間存放中間比較結果,就是樹形結構的所有根節點。S(n) = O(n)

    ④???穩定性:穩定排序。

    ⑤???程序:

    3、??堆排序:

    ①???思想:把待排序記錄的關鍵字存放在數組r[1…n]中,將r看成是一刻完全二叉樹的順序表示,每個節點表示一個記錄,第一個記錄r[1]作為二叉樹的根,一下個記錄r[2…n]依次逐層從左到右順序排列,任意節點r[i]的左孩子是r[2i],右孩子是r[2i+1],雙親是r[i/2向下取整]。然后對這棵完全二叉樹進行調整建堆。

    ②???時間復雜度:T(n) = O(nn)

    ③???空間復雜度:S(n) = O(1)

    ④???穩定性:不穩定排序。{5?5?3}

    ⑤???程序:

    (1)?????調整堆:

    [cpp]?view plaincopy
  • void?sift(RecordType?r[],?int?k,?int?m)??
  • {??
  • ????/*假設r[k...m]是以r[k]為根的完全二叉樹,而且分別以r[2k]和r[2k+1]為根的左右子樹為大根堆,調整r[k],使整個序列r[k...m]滿足堆的性質*/??
  • ????t?=?r[k];/*暫存“根”記錄r[k]*/??
  • ????x?=?r[k].key;??
  • ????i?=?k;??
  • ????j?=?2?*?i;??
  • ????finished?=?FALSE;??
  • ????while(j?<=?m?&&?!finished)??
  • ????{??
  • ????????if(j?<?m?&&?r[j].key?<?r[j?+?1].key)??
  • ????????????j?=?j?+?1;/*若存在右子樹,且右子樹根的關鍵字大,則沿右分支“篩選”*/??
  • ????????if(x?>=?r[j].key)??
  • ????????????finished?=?TRUE;/*篩選完畢*/??
  • ????????else??
  • ????????{??
  • ????????????r[i]?=?r[j];??
  • ????????????i?=?j;??
  • ????????????j?=?2?*?i;??
  • ????????}/*繼續篩選*/??
  • ????}??
  • ????r[i]?=?t;/*將r[k]填入到恰當的位置*/??
  • }??
  • (2)?????建初堆:

    [cpp]?view plaincopy
  • void?crt_heap(recordType?r[],?int?length)??
  • {??
  • ????n?=?length;??
  • ????for(i?=?n?/?2;?i?>=?1;?--i)/*自第n/2向下取整?個記錄開始進行篩選建堆*/??
  • ????????sift(r,?i,?n);??
  • }??
  • (3)?????堆排序:

    [cpp]?view plaincopy
  • void?HeapSort(RecordType?r[],?int?length)??
  • {??
  • ????crt_heap(r,?length);??
  • ????n?=?length;??
  • ????for(i?=?n;?i?>=?2;?--i)??
  • ????{??
  • ????????b?=?r[1];/*將堆頂記錄和堆中的最后一個記錄互換*/??
  • ????????r[1]?=?r[i];??
  • ????????r[i]?=?b;??
  • ????????sift(r,?1,?i?-?1);/*進行調整,使r[1…i-1]變成堆*/??
  • ????}??
  • }??
  • 五、歸并排序:

    (一)???思想:

    (二)???分類:

    1、??歸并排序:

    ①???思想:假設初始序列右n個記錄,首先將這n個記錄看成n個有序的子序列,每個子序列的長度為1,然后兩兩歸并,得到n/2向上取整?個長度為2n為奇數時,最后一個序列的長度為1)的有序子序列。在此基礎上,在對長度為2的有序子序列進行兩兩歸并,得到若干個長度為4的有序子序列。如此重復,直至得到一個長度為n的有序序列為止。

    ②???時間復雜度:T(n) = O(nn)

    ③???空間復雜度:S(n) = O(n)

    ④???穩定性:穩定排序。

    ⑤???程序:

    [cpp]?view plaincopy
  • void?Merge(RecordType?r1[],?int?low,?int?mid,?int?high,?RecordType?r2[])??
  • {??
  • ????/*已知r1[low...mid]和r1[mid?+?1...high]分別按關鍵字有序排列,將它們合并成一個有序序列,存放在r2[low...high]*/??
  • ????i?=?low;??
  • ????j?=?mid?+?1;??
  • ????k?=?low;??
  • ????while((i?<=?mid)?&&?(j?<=?high))??
  • ????{??
  • ????????if(r1[i].key?<=?r1[j].key)??
  • ????????{??
  • ????????????r2[k]?=?r1[i];??
  • ????????????++i;??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????r2[k]?=?r1[j];??
  • ????????????++j;??
  • ????????}??
  • ????????++k;??
  • ????}??
  • ????while(i?<=?mid)??
  • ????{??
  • ????????r2[k]?=?r1[i];??
  • ????????k++;??
  • ????????i++;??
  • ????}??
  • ????while(j?<=?high)??
  • ????{??
  • ????????r2[k]?=?r1[j];??
  • ????????k++;??
  • ????????j++;??
  • ????}??
  • }??
  • void?MSort(RecordType?r1[],?int?low,?int?high,?RecordType?r3[])??
  • {??
  • ????/*r1[low...high]經過排序后放在r3[low...high]中,r2[low...high]為輔助空間*/??
  • ????RecordType?r2[N];??
  • ????if(low?==?high)??
  • ????r3[low]?=?r1[low];??
  • ????else??
  • ????{??
  • ????????mid?=?(low?+?high)?/?2;??
  • ????????MSort(r1,?low,?mid,?r2);??
  • ????????MSort(r1,?mid?+?1,?high,?r2);??
  • ????????Merge(r2,?low,?mid,?high,?r3);??
  • ????}??
  • }??
  • void?MergeSort(RecordType?r[],?int?n)??
  • {??
  • ????/*對記錄數組r[1...n]做歸并排序*/??
  • ????MSort(r,?1,?n,?r);??
  • }??
  • 六、分配類排序:

    (一)???思想:分配類排序是利用分配和收集兩種基本操作。

    (二)???分類:

    1、??多關鍵字排序:

    2、??鏈式基數排序:

    ①???思想:先分配,再收集,就是先按照一個次關鍵字收集一下,然后進行收集(第一個排序),然后再換一個關鍵字把新序列分配一下,然后再收集起來,又完成一次排序,這樣所有關鍵字分配收集完后,就完成了排序。

    ②???時間復雜度:T(n) = O( d ( n + rd ) )

    ③???空間復雜度:S(n) = O(rd)

    ④???穩定性:穩定排序。

    ⑤???程序:

    七、總結:

    (1)簡單排序法一般只用于n較小的情況(例如n<30)。當序列的記錄“基本有序”時,直接插入排序是最佳的排序方法。如果記錄中的數據較多,則應采用移動次數較少的簡單選擇排序法。

    (2)快速排序、堆排序和歸并排序的平均時間復雜度均為O(nn),但實驗結果表明,就平均時間性能而言,快速排序是所有排序方法中最好的。遺憾的是,快速排序在最壞情況下的時間性能為O(n2)。堆排序和歸并排序的最壞時間復雜度仍為O(nn),當n較大時,歸并排序的時間性能優于堆排序,但它所需的輔助空間最多。

    (3)可以將簡單排序法與性能較好的排序方法結合使用。例如,在快速排序中,當劃分子區間的長度小于某值時,可以轉而調用直接插入排序法;或者先將待排序序列劃分成若干子序列,分別進行直接插入排序,然后再利用歸并排序法,將有序子序列合并成一個完整的有序序列。

    (4)基數排序的時間復雜度可以寫成O(d·n)。因此,它最適合于n值很大而關鍵字的位數d較小的序列。當d遠小于n時,其時間復雜度接近O(n)

    (5)從排序的穩定性上來看,在所有簡單排序法中,簡單選擇排序是不穩定的,其他各種簡單排序法都是穩定的。然而,在那些時間性能較好的排序方法中,希爾排序、快速排序、堆排序都是不穩定的,只有歸并排序、基數排序是穩定的。


    常考的排序:選擇排序、折半插入、冒泡

    總結

    以上是生活随笔為你收集整理的数据结构中的各种排序---总结篇的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。