上次我們對冒泡排序進行了簡單的介紹,需要了解的朋友可以不妨去看一下排序算法之冒泡排序。今天要說的快速排序和冒泡排序一樣,也是交換排序。
首先了解一下快速排序的思想:
選擇一個基準元素,(通常選擇第一個元素或者最後一個元素)通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,然後再用同樣的方法遞歸地排序劃分的兩部分。
說起來比較簡單,接下來看看如何用代碼去實現
public static void quickSort(int[] array, int start, int end){
if(start < end){
//經過一次排列後,獲得基準元素所處的位置
int position = getPartition2(array, start, end);
quickSort(array, start, position-1);
quickSort(array, position+1, end);
}
}
可以看到,遞歸排序思路很清晰,但關鍵的一步在於如何將待排序列分成兩部分,並返回基準元素的位置。在如何進行分組的處理上,一般有兩種方法:
private static int getPartition(int[] array, int start, int end){
//以第一個元素爲基準元素
int baseNum = array[start];
//從前向後遍歷的索引
int startIndex = start;
//從後向前遍歷的索引
int endIndex = end;
while(startIndex < endIndex){
//從後向前遍歷,找出小於基準元素值的元素位置
while(array[endIndex] >= baseNum && startIndex < endIndex)
endIndex--;
array[startIndex] = array[endIndex];
//從前向後遍歷,找出大於基準元素值的元素位置
while(array[startIndex] <= baseNum && startIndex < endIndex)
startIndex++;
array[endIndex] = array[startIndex];
}
array[startIndex] = baseNum;
return startIndex;
}
這種方法,以第一個元素爲基準元素,我們用變量獲得第一個元素的值,這就相當於第一個元素位置爲空,所以我們從序列的後面向前遍歷,獲得小於基準元素值的元素,將獲得的元素放到第一個元素的位置,這樣就相當於獲得的元素的位置爲空了,然後我們在從前向後遍歷,獲得大於基準元素的元素,再放到後面爲空的位置上……,依次循環下去,直到前後兩個索引相等,跳出循環,此時兩個索引指向同一個位置,且該位置爲空,最後將該位置放置基準元素。自此我們將一個序列,以第一個元素爲準,左邊的小於該元素,右邊的大於該元素。
不過需要注意的一點是,如果序列中有第一個元素有重複元素,那麼在從後向前搜索或從前向後搜索時,判斷條件應該是>=和<=,否則會陷入死循環。
第二種方法,更加巧妙
private static int getPartition2(int[] array, int start, int end){
int baseNum = array[end];
int back = start-1;
int front = 0;
for (front = start; front < end; front++) {
if(array[front] < baseNum){
back++;
swap(array, back, front);
}
}
swap(array, back+1, end);
return back+1;
}
使用一前一後兩個索引,以最後一個元素爲基準,從前向後遍歷,前索引一直向前走,當前索引指的元素小於基準元素時,後索引前進一步,將前後索引所指的元素進行交換,直至遍歷結束。希望能按照步驟自己演示一遍,該算法設計的非常巧妙。最後後索引的後一個元素的值一定是大於基準元素的,所以該元素和最後一個元素進行交換。
最後讓我們看一下測試代碼
public static void main(String[] args) {
int[] array = new int[100];
Random random = new Random();
for(int i = 0; i < array.length; i++){
array[i] = random.nextInt(200);
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println("\n排序後");
quickSort(array, 0, array.length-1);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
至此,快速排序算法結束。推薦一個博客
v_JULY_v該博主非常強大,對算法理解很是透徹,有想深入瞭解算法的朋友,可以多看看