排序算法之快速排序

上次我們對冒泡排序進行了簡單的介紹,需要了解的朋友可以不妨去看一下排序算法之冒泡排序。今天要說的快速排序和冒泡排序一樣,也是交換排序。

首先了解一下快速排序的思想:

選擇一個基準元素,(通常選擇第一個元素或者最後一個元素)通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,然後再用同樣的方法遞歸地排序劃分的兩部分。

說起來比較簡單,接下來看看如何用代碼去實現

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該博主非常強大,對算法理解很是透徹,有想深入瞭解算法的朋友,可以多看看

点赞