快速排序是一種高效的排序算法,也是面試常考的一種算法,大多數人畏懼和逃避算法,不是由於算法有多難,而是沒有找到合適的老師,簡單說就是沒有通俗易懂的文章,致使學習者越看越懵,看完即忘的現象。今天我想嘗試作一個「好老師」,用通俗易懂的方式講解一下什麼是快速排序。java
不少文章,上來就用某種語言,開始啪啦啪啦寫代碼,不熟悉該種語言的學者,一臉矇蔽,又是一篇水文。或者跟着代碼看了一下,感受會了,關掉網頁,腦子:what???我剛纔看了啥?面試
算法與編程語言無關,它是一種思想,理解了思想,編程語言只是一種實現方式。算法
OK,來看看快速排序的思想編程
假設如今有一個亂序的數組:數組
5 3 6 1 4 8 2 7
複製代碼
快速排序核心思想:編程語言
隨意找一個目標值,放在數組的某個下標,使得該下標的左側數值都小於目標值,右側數值都大於目標值學習
隨意選一個目標值,假如就數組的第一個數值 5,如今須要將 5 移動到數組的某個下標 K 上,而且以 K 爲臨界點,左邊的數小於 5 ,右邊的數大於 5 ,該怎麼操做?ui
使用一種二分交換的思想,以什麼分?如下標 K 分。須要解決2個問題,如何交換數值,如何肯定下標 Kspa
模擬兩我的,從數組 5 3 6 1 4 8 2 7
兩邊開始探測,先從右往左開始找一個小於5的數,再從左往右找一個大於5的數,而後交換數據,交換完成繼續探測,直到兩我的相遇code
模擬的兩我的暫且稱它們爲:"探子j" , "探子i"
開始時,"探子j" 站在 右邊,"探子i" 站在 左邊
5 3 6 1 4 8 2 7 => 5 3 2 1 4 8 6 7
在現有的位置上繼續探測,仍是從 "探子j" 開始(強調,每次都是從探子j開始),繼續向左移動(j- -),找到 4 知足,停下來;而後 "探子i" 開始繼續往右尋找,走到 4 沒有找到大於 5 的數字兩我的就相遇了。(若是相遇以前能找到知足的數值,則依舊交換這兩個值)
當兩個探子相遇的下標位置,就是下標 K,此時將下標 K 數值與以前選擇的 基準數 相互交換,實現 K 的左邊都小於基準數,右邊大於基準數
4 3 2 1 5 8 6 7
以 K (5) 作分界點,將數組分爲兩個部分,而後將左右兩邊的子數組在執行上述操做,最終將整個數組完成排序
OK,以上就是快速排序的基本思想,應該能夠理解吧。
理解了思想,就按照這算法的思想一步步寫代碼就好了,本人熟悉java,就用java做爲編程語言擼一遍
/** * 快速排序 * * @param array 目標數組 * @param left 數組最左下標值 * @param right 數組最右下標值 */
public static void quickSort(int[] array, int left, int right) {
//防止數組越界(這一步最後再回來理解)
if (left >= right) return;
int base = array[left];//基準數
int i = left, j = right;//左探子i,右探子j
int temp;//用於交換的臨時變量
while (i != j) {//兩個探子相遇前
//找出小於 基準數 的下標,當大於等於 基準數 的時候,探子j 向左移動便可(j--)
while (array[j] >= base && i < j) {
j--;
}
//找出大於 基準數 的下標,當小於等於 基準數 的時候,探子i 向右移動便可(i++)
while (array[i] <= base && i < j) {
i++;
}
//通過上面兩個循環以後,探子j,探子i 都會停在符合條件的值的下標上面,而後就能夠進行交換值啦
if (i < j) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
//通過上面的循環以後會觸發 i=j 的條件(即兩個探子相遇),此時將基準值的數與i或者j(隨便哪一個都同樣)下標的值交換,完成一次交換探測
array[left] = array[i];//基準值的位置
array[i] = base;//基準值
//完成交換以後再對左右兩邊的子數組進行遞歸調用走上面的方法,完成整個數組的排序
quickSort(array, left, i - 1);//左邊
quickSort(array, i + 1, right); //右邊
}
複製代碼
讀註釋!讀註釋!讀註釋!而後就是,使用快排算法排序數組
int[] array = new int[]{5, 3, 6, 1, 4, 8, 2, 7};
quickSort(array, 0, array.length - 1);//快速排序
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");//打印排序後的數組
}
複製代碼
結果輸出
1 2 3 4 5 6 7 8
複製代碼