內部排序演算法小結

2021-07-03 18:05:35 字數 2578 閱讀 8351

排序演算法大體上可分為內部排序和外部排序。所謂外部排序,就是指計算機的記憶體有限,不能將龐大的序列全部載入到記憶體中進行排序,就需要訪問外部儲存裝置來進行排序。內部排序,當資料量不是非常大時,可以一次性載入到記憶體中進行排序的統稱。

按照排序依據的不同原則,可將內部排序演算法分為插入排序、交換排序、選擇排序、歸併排序和基數排序。下面我主要講各種排序演算法的原理,實現由小到大的排序,具體的實現方式可以參見我的github: 。

插入排序(insert sort)

插入排序是比較常見的排序方式,主要有直接插入排序和希爾排序。

直接插入排序比較簡單,實現**也很短。其原理就是依次遍歷整個序列,當該值小於其前一位的值時,就將前一位的值給予該值,並迴圈比較與更前一位的大小,直到條件不能滿足。當序列遍歷完時,序列就按照由小到大依次排列了。

希爾排序相對直接插入排序來講,就比較麻煩了。設定序列為a,長度為n,將步長step定為n/2,遍歷序列,比較a[i]與a[i+step]的大小,後者小的話就交換位置,並迴圈比較a[i-step]與a[i],這樣進行了第一遍的遍歷。接下來將step再減半,迴圈進行上述操作,直到最後step為0,迴圈結束,此排序方法的核心就是迴圈比較值與其相隔step步長值進行比較,**如下:

for(int i=step; i=0 && a[j]>base)

a[j+step] = base;

}

交換排序(exchange sort)

交換排序主要有大家比較常見的氣泡排序和效率比較高的快速排序了。

氣泡排序,顧名思義,就是依次遍歷,將比較「冒泡」的比較大的值排到後面去,所以遍歷一次排序後最大的值就被排到了最後。再遍歷依次,剩餘最大的就被拍到了此時序列的最後,迴圈遍歷直到最後乙個值就ok了。

快排是執行時間複雜度比較小的排序方法。快排的思想就是將序列分成兩部分,第一部分是值全部比序列第乙個值a[0]小的,第二部分是值全部不比a[0]小的。之後遞迴上述兩部分,最後的時候,就可將序列拍好序了。有乙個比較巧的方法,其核心如下所示:

int base=a[low];

while(low=a[low]) low++;

a[high] = a[low];

}a[low] = base;

選擇排序 (select sort)

選擇排序有直接選擇排序和堆排序。

直接選擇排序,顧名思義,就是選擇序列中a[0]後面最小的值,和a[0]交換,然後迴圈選擇序列中a[1]後面最小的值,和a[1]交換,直到最後迴圈完畢,序列也就排好了。

堆排序稍微複雜點。堆,這裡指的是大根堆的完全二叉樹。所謂大根堆,是指完全二叉樹中所有的子節點都不能大於父節點。堆排序主要分為兩個部分:part1,將序列調整成大根堆;part2,將大根堆的根節點和最後乙個葉子節點交換,如此一來,序列中最大的值就被拍到了最後,然後迴圈part1和part2,直到最後剩乙個根節點,就將序列排列好了。核心**如下:

void heap_adjust(int *a, int n)

j = (j-1)/2;

if(j==0) flag++;

} }}void heap_sort(int *a, int n)

}

歸併排序(merge sort)

歸併排序是指將兩個或多個已經排好的序列合併成乙個序列。該演算法的原理也比較簡單,在外部排序的時候必須要用到。依次比較兩個序列的最小值,將更小的賦值給新序列直到兩個序列的末端。

基數排序(分布式排序)

基數排序,又稱桶排序,不同於上述所有的排序方法,基數排序不需要進行序列中數的比較,實現排序主要是通過關鍵字的比較和移動記錄這兩種操作。比較數值時是將序列中的值分別放入0~9的十個桶中。放置的原理就是首先比較個分位,將該值放入相應的桶中,然後依次比較上述桶中值的十分位,再放入對應的0~9桶中,直到比較完序列中的最高位為止(這裡採用最低位優先的方法,即lsd)。當有的數沒有高位時,就置為0,比如數字「9」,其十分位就為0。基數排序其實不太適合比較序列為數值時的情況,其比較適合比較序列為時間、字串時候的情況,比較字串時將不足長度的字串末尾置0。比較數值時,其核心**如下:

void radix_sort(int *a, int n, int max){//a為陣列,n為陣列長度,max為陣列最高位數

int num = 0;

for(; num//放入桶中後,再把陣列重新串起來,方便再放入桶中

for(j=0; j各方法比較討論:

從平均時間效能而言,快速排序最佳,其所需時間 最短。但是快速排序最壞情況下的時間效能不如堆排序和歸併排序。直接插入排序適合記錄「基本有序」或n較小時,因此其可以和快排、歸併排序結合在一起使用。基數排序適用於n值很大而關鍵字較小的序列。排序演算法的穩定性,假定待排序的序列中,存在多個具有相同關鍵字的記錄,經過排序後,這些記錄相對次序儲存不變,則稱這中排序演算法是穩定的,否則不穩定。上述排序演算法中,基數排序是穩定的,時間複雜度為o(n2)的直接插入排序、冒泡、直接選擇排序也是穩定的,而時間效能較好的快排、堆排序和希爾排序都是不穩定的。

總的來說,沒有哪乙個排序演算法是絕對的最好或效能最佳,它們的適用場景也不同,有的適合n較小,有的適合n較大,在實際使用時可根據情況選擇,必要時可以結合使用。內部排序中,用「比較」進行排序的演算法在最壞情況下能達到的最好的時間複雜度為o(nlogn)。

內部排序演算法

內部排序是指待排序列完全存放在記憶體中所進行的排序過程,適合不太大的元素序列。1.快速排序int partition int a,int low,int high a low a high while low2.並歸排序 void merging int list1,int list1 size,i...

內部排序演算法

內部排序演算法就是指記憶體中的排序演算法,而外部排序演算法則是指待排序資料過多,無法一次性載入到記憶體中,排序過程需要讀取磁碟,因此需要考慮磁碟 io 的消耗!內部排序演算法按照操作型別可大致分為五類 插入排序 交換排序 選擇排序 歸併排序 計數排序 內部排序演算法按照時間複雜度可大致分為三類 簡單...

排序演算法小結

1 快速排序 quicksort 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來說,它是歸併排序的就地版本。快速排序可以由下面四步組成。1 如果不多於1個資料,直接返回。2 一般選擇序列最左邊的值作為支點資料。3 將序列分成2部分,一部分都大於支點資料,另外一部分都小於支點資料。4...