1. 程式人生 > 其它 >[演算法] 排序演算法總結

[演算法] 排序演算法總結

總述

借圖侵刪

SHELL排序

時間複雜度:O(N^(X)) (X<=2)

又稱“縮小增量排序”,是插入排序的進化版,其高效之處在於通過增量間隔的比較和交換,比樸素的插入排序減少了交換次數,從而提高了效率。感性認知來講,確實可以提高演算法效率,但是我不會證明該演算法的時間複雜度。

 1 void Shell_sort(int l, int r)
 2 {
 3     int gap = r - l + 1;
 4     int tep = 0;
 5     do
 6     {
 7         gap = gap / 3 + 1;
 8         for (int
i = l + gap; i <= r; ++i) 9 { 10 if (a[i - gap] > a[i]) 11 { 12 tep = a[i]; 13 int j = i - gap; 14 do 15 { 16 a[j + gap] = a[j]; 17 j -= gap; 18 } while
(j >= l && a[j] > tep); 19 a[j + gap] = tep; 20 } 21 } 22 }while (gap > 1); 23 }

歸併排序

時間複雜度:O(N*logN)

分治的思想+O(N)合併有序陣列。

22 void GB_sort(int l, int r)
23 {
24     if (l == r)    return;
25     int mid = (l + r) >> 1;
26     GB_sort(l, mid), GB_sort(mid + 1
, r); 27 int t1 = l, t2 = mid + 1, t3 = l; 28 for (int i = l; i <= r; ++i) 29 if ((a[t1] <= a[t2] && t1 <= mid) || t2 == r + 1) b[t3] = a[t1], ++t1, ++t3; 30 else b[t3] = a[t2], ++t2, ++t3; 31 for (int i = l; i <= r; ++i) 32 a[i] = b[i]; 33 }

堆排序

時間複雜度:O(N*logN)

本質上就是維護一個大根堆。也是選擇排序的一種。

注意堆的初始化要自下而上!因為update函式是自上而下更新的,向下可以保證操作到位,而向上無法進行。

 1 void update(int x, int m)
 2 {
 3     int t = lson(x);
 4     if (t > m) return;
 5     if (t < m && a[t + 1] > a[t]) ++t;
 6     if (a[t] > a[x]) swap(a[x], a[t]);
 7     update(t, m);
 8 }
 9 
10 void HEAP_sort()
11 {
12     for (int i = n; i >= 1; --i)
13         update(i, n);
14     for (int i = n - 1; i >= 1; --i) // 每次取出最大值並維護堆
15     {
16         swap(a[i + 1], a[1]);
17         update(1, i);
18     }
19 }

快速排序

時間複雜度:平均O(N*logN)

交換排序的一種,具體流程如下:

選擇基準值---將小於基準值的值置於基準值之前,將大於基準值的值置於基準值之後---遞迴

不難看出這個演算法是很容易被卡成N^2的,故手寫時應至少加一個隨機化(雖然很少去手寫)。

 1 void Quick_sort(int l, int r)
 2 {
 3     if (l >= r) return;
 4     int i = l, j = r;
 5     int x = a[i];
 6     while (i < j)
 7     {
 8         while (i < j && a[j] > x) --j;
 9         if (i < j) a[i++] = a[j];
10         while (i < j && a[i] < x) ++i;
11         if (i < j) a[j--] = a[i];
12     }
13     a[i] = x;
14     Quick_sort(l, i - 1);
15     Quick_sort(i + 1, r);
16     return;
17 }

所以為什麼快速排序叫做快排?手寫起來慘不忍睹還會被卡