排序 是將一組亂的數據按一定準則排好順序。
一般按照時間複雜度大概分爲三類:
一: O(n^2) 冒泡排序,選擇排序,插入排序,希爾排序(性能優於O(n^2),差於O(nlog));
二: O(nlogn) 快速排序,歸併排序,堆排序;
三: O(n) 基數排序,桶排序,計數排序。
根據其穩定性:穩定排序和不穩定排序。
穩定性排序:值相同的兩個元素排序完,它兩的相對位置不變。如下圖:黃色的 6 和 白色的 6 值一樣排完序後,黃色 6 仍在白色 6 的前面則是穩定排序。
穩定排序:冒泡排序,插入排序,歸併排序,計數排序,桶排序,基數排序;
不穩定排序:選擇排序,希爾排序,快速排序,堆排序;
1.冒泡排序
定義:反覆的走訪要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來,這個工作反覆的進行直至沒有元素需要交換。
由於這篇是排序總結,冒泡的詳解大家可以看一下我之前寫的冒泡的文章: 冒泡排序的詳解和優化。
冒泡排序的時間複雜度是O(n^2),空間複雜度是O(1),穩定性排序。
雞尾酒排序:是冒泡排序的一個版本,是從頭比較到尾部後又從尾部比較回來。適用於絕大多數已經排好序的情況。具體實現:雞尾酒排序詳解
2. 選擇排序
定義:冒泡排序的一種優化,每次循環找到剩下數列元素中最小(大)的數交換到剩下元素數列的最前面。
優點:它相對與冒泡排序大大減少了交換次數(減少好多到內存中讀寫,減少cpu工作量,提高性能),只是剩下元素最小(大)的數和剩下元素中最前面的數交換。
具體的實現:選擇排序詳解
時間複雜度也是O(n^2),空間複雜度O(1),不穩定排序。
3. 插入排序:
定義:對於未排序的數據,在已排好的序列中從後往前掃描,找到合適的位置並插入。
優點:對於大部分元素是有序的,這種方法十分划算。
時間複雜度最壞O(n^2),最好O(n);空間複雜度 O(1),穩定排序。
具體詳解:直接插入排序詳解
二分插入排序:一種插入排序,在插入有序數列時,使用二分法查找位置,具體實現大家自己實現一下。
4. 希爾排序:
定義:又叫縮小量排序,插入排序的優化版。把待排序的數組按一定數量的分組,對每組使用直接插入排序算法排序;然後再縮小數量繼續分組排序,直至整個數組分成一組,排序完成。
具體詳情:希爾算法詳解
時間複雜度小於O(n^2),空間複雜度O(1),不穩定排序。
優點:對於大部分元素亂的時候,插入排序的優化。
5. 歸併排序:
定義:利用遞歸與分治技術將數據序列劃分成爲越來越小的半子表,在對半子表排序後,再用遞歸方法將排好的半子表合成爲越來越大的有序序列。
具體實現:歸併詳解
時間複雜度O(nlogn) 空間複雜度O(n),穩定排序。
6. 快速排序:
定義:冒泡排序的改進,分治的典型。選擇一個基數,分別從數組的左邊和右邊與基數比較,大的放在基數的右邊,小的放在基數左邊。然後,再在基數的左右選擇基數排序直至最後數組排序好。
具體實現:快速排序詳解
時間複雜O(nlogn),空間複雜O(logn),不穩定排序。
7.堆排序:
定義:利用完全二叉樹的特性,實現排序。每次取出最大(小)堆的根節點進行排序。
具體實現:堆排序詳解
想直接獲取最大(小)值: 優先隊列詳解
時間複雜度O(nlogn),空間複雜度O(1),不穩定排序。
8. 計數排序:
定義:用一個數組從小到大記錄數組中相應大小數的次數,然後遍歷這個數組記錄的次數排序。
具體實現:計數排序詳解
時間複雜度O(n+k),空間複雜度O(k)穩定排序。
特點:1.只適合整數排序,2.對數據跨度大的不適合,3.不進行比較的排序算法
9. 桶排序:
定義:利用某種函數映射關係將數據分佈到有限數量的桶中,每個桶分別排序。
具體實現:桶排序詳解
時間複雜度O(n+k),空間複雜度O(n+k)穩定排序。
特點:減少了幾乎所有的比較。
10.基數排序:
定義:按照從右往左的順序,依次將每一位都當作一次關鍵字,然後按照該關鍵字對數組排序,同時每一輪排序都基於上輪排序後的結果;當將所有的位排序完之後,整個數組都達到了有序狀態。
基數是什麼呢?對於十進制整數,每一位都可能是0~9其中的某一個,總共10種可能,那10就是它的基數。同理二進制數字基數爲2,字符串如果使用的是8位的擴展ASCII字符集,那麼基數是256.
具體實現:基數排序詳解
時間複雜度O(n+k),空間複雜度O(n+k)穩定排序。
總結:
1. 時間複雜度由小到大:O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)
2. 冒泡,選擇,插入排序需要兩個for循環,每次只關注一個元素,平均時間複雜度O(n^2)(一遍找元素O(n), 一遍找位置O(n));
快速,歸併,堆基於分治思想,log以2爲底,平均時間複雜度O(nlogn) (一遍找元素O(n),一遍找位置O(logn));
希爾排序依賴增量序列的性質,但目前沒有最好的。例如希爾增量序列時間複雜度爲O(n^2),Hibbard增量序列時間複雜度 爲O(n^(1/2))。
3. 從平均時間來看,快速排序的效率最高,
快速排序的平局時間複雜度是O(nlogn),雖然歸併也是O(nlogn)。但是,快速中的 n 會比歸併中的小很多;
堆排序的平均時間複雜度也是O(nlogn),但是堆排序每次取出最大(小)值 ,都會進行堆重排,消耗很多性能。
4. 最後ps上總結表,拿走不謝: