通過一趟排序將要排序的數據分割成獨立的兩部分:分割點左邊都是比它小的數,右邊都是比它大的數。然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
快速排序原理【轉載】:
第一步:設置兩個指針left和right分別指向數組的頭部和尾部,並且以頭部的元素(6)為基准數
第二步:right指針先往左移動,找到小於基准數的元素就停下,然后移動left指針
第三步:left指針往右移動,找到大於基准數的元素就停下,然后交換right和left指針所值元素的值
重復第二、三步,直到兩個指針left和right重合
第四步:兩個指針重合后將基准數(6)與兩個指針指向的元素值(3)交換
到這時,第一輪排序結束,此時以基准數(6)為分界點,(6)左邊的數都小於等於6,(6)右邊的數都大於等於6,現在我們已經將原來的序列以(6)為分界點拆成了兩個序列左邊的序列是3 1 2 5 4,右邊的序列是9 7 10 8,接下來分別處理這兩個序列,原理相同。
最終序列為1 2 3 4 5 6 7 8 9 10,到此排序完全結束(快速排序的每一輪處理其實就是將這一輪的基准數歸位,直到所有的數都歸位為止)
注:為什么是right先移動,不能是left先移動?
假設需要排列的數組為[ 0 , 1 ],如果先移動左邊指針。此時左指針會移動到1的位置,因此右指針(原本就在1的位置)位置不變。此時將基准書與指針指向的數字進行交換,結果就變成了[ 1 , 0 ],而實際情況我們需要的是左邊比基准數小,右邊比基准數大,所以產生的結果就完全相反了。
下面附上實現代碼:
package algorithmimplementation; public class QuickSort { public static void main(String[] args) { int[] num = new int[]{6,1,2,7,9,3,4,5,10,8}; for(int a:quickSort(num, 0, num.length-1)) { System.out.print(a+" "); } } public static int[] quickSort(int[] num, int leftPos, int rightPos) { if(rightPos < leftPos) return num; else { //將數列最左邊第一個數字作為基准數 int initLeftPos = leftPos; int initRightPos = rightPos; int baseNum = num[leftPos]; while(rightPos > leftPos) { //第二步:右邊指針找到小於基准數的就停下 while(num[rightPos] >= baseNum & rightPos > leftPos) { rightPos--; } //第二步:左邊指針找到大於基准數的就停下 while(num[leftPos] <= baseNum & rightPos > leftPos) { leftPos++; } //交換兩個指針最終標記的數字 if(rightPos > leftPos) swap(num,leftPos,rightPos); } //當左右兩邊指針重合時,將基准數與指針指向數字交換 swap(num,leftPos,initLeftPos); //指針左半邊遞歸,以進來的數組的左邊為界,右邊是左右指針相同時左邊一個 quickSort(num, initLeftPos, leftPos-1); //右邊同理 quickSort(num, rightPos+1, initRightPos); return num; } } //swap方法:將數組中leftPos和rightPos上的兩個數值進行交換 public static void swap(int[] num,int leftPos,int rightPos) { int temp = num[leftPos]; num[leftPos] = num[rightPos]; num[rightPos] = temp; } }