原文出處:
1. 白話經典算法系列之八 MoreWindows白話經典算法之七大排序總結篇
3. 常見排序算法小結
本篇主要整理了冒泡排序,直接插入排序,直接選擇排序,希爾排序,歸並排序,快速排序,堆排序七種常見算法,是從上面三篇博文中摘抄整理的,非原創。
一、冒泡排序
主要思路是:
通過交換相鄰的兩個數變成小數在前大數在后,這樣每次遍歷后,最大的數就“沉”到最后面了。重復N次即可以使數組有序。
冒泡排序改進1:
在某次遍歷中,如果沒有數據交換,說明整個數組已經有序,因此通過設置標志位來記錄此次遍歷有無數據交換就可以判斷是否要繼續循環。
冒泡排序改進2:
記錄某次遍歷時最后發生數據交換的位置,這個位置之后的數據顯然已經有序。因此設置標志位記錄每次遍歷中最后發生數據交換的位置可以確定下次循環的范圍。
二、直接插入排序
主要思路是:
每次將一個待排序的數組元素,插入到前面已排序的序列中這個元素應該在的位置,直到全部數據插入完成。類似撲克牌洗牌過程。
三、直接選擇排序
主要思路是:
數組分成有序區和無序區,初始時整個數組都是無序區,每次遍歷都從無序區選擇一個最小的元素直接放在有序區最后,直到排序完成。
四、快速排序
主要思路是:
“挖坑填數 + 分治法”,首先令i = L;j = R;將a[i]挖出形成打一個坑,稱a[i]為基准數。然后j--從后向前找到一個比基准數小的數,挖出來填到a[i]的坑中,這樣a[j]就形成了一個新的坑,再i++從前向后找到一個比基准數大的數填到a[j]坑中。重復進行這種挖坑填數,直到i = j。這時a[i]形成了一個新的坑,將基數填到a[i]坑中,這樣i之前的數都比基准數小,i之后的數都比基准數大。因此將數組分成兩部分再分別重復上述步驟就完成了排序。
五、希爾排序
主要思路是:
先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然后依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。由於希爾排序是對相隔若干距離的數據進行直接插入排序,因此可以形象的稱希爾排序為“跳着插”。
六、歸並排序
主要思路是:
當一個數組左邊有序,右邊也有序,那合並這兩個有序數組就完成了排序。如何讓左右兩邊有序了?用遞歸!這樣遞歸下去,合並上來就是歸並排序。
七、堆排序
堆排序的難點就在於堆的的插入和刪除。
堆的插入就是——每次插入都是將新數據放在數組最后,而從這個新數據的父結點到根結點必定是一個有序的數列,因此只要將這個新數據插入到這個有序數列中即可。
堆的刪除就是——堆的刪除就是將最后一個數據的值賦給根結點,然后再從根結點開始進行一次從上向下的調整。調整時先在左右兒子結點中找最小的,如果父結點比這個最小的子結點還小說明不需要調整了,反之將父結點和它交換后再考慮后面的結點。相當於從根結點開始將一個數據在有序數列中進行“下沉”。
因此,堆的插入和刪除非常類似直接插入排序,只不是在二叉樹上進行插入過程。所以可以將堆排序形容為“樹上插”
再用一張圖表示下這七種常用的排序方法的關系。
最后給出一張各算法的性能比較圖