快速排序!!

方法其實很簡單:分別從初始序列“6 1 2 7 9 3 4 5 10 8”兩端開始“探測”。先從找一個小於6的數,再從找一個大於6的數,然後交換他們。這裏可以用兩個變量i和j,分別指向序列最左邊和最右邊。我們爲這兩個變量起個好聽的名字“哨兵i”和“哨兵j”。剛開始的時候讓哨兵i指向序列的最左邊(即i=1),指向數字6。讓哨兵j指向序列的最右邊(即=10),指向數字。

這裏寫圖片描述
首先哨兵j開始出動。因爲此處設置的基準數是最左邊的數,所以需要讓哨兵j先出動,這一點非常重要(請自己想一想爲什麼)。哨兵j一步一步地向左挪動(即j–),直到找到一個小於6的數停下來。接下來哨兵i再一步一步向右挪動(即i++),直到找到一個數大於6的數停下來。最後哨兵j停在了數字5面前,哨兵i停在了數字7面前。
這裏寫圖片描述
這裏寫圖片描述
現在交換哨兵i和哨兵j所指向的元素的值。交換之後的序列如下:

6 1 2 5 9 3 4 7 10 8
這裏寫圖片描述
這裏寫圖片描述
到此,第一次交換結束。接下來開始哨兵j繼續向左挪動(再友情提醒,每次必須是哨兵j先出發)。他發現了4(比基準數6要小,滿足要求)之後停了下來。哨兵i也繼續向右挪動的,他發現了9(比基準數6要大,滿足要求)之後停了下來。此時再次進行交換,交換之後的序列如下:

6 1 2 5 4 3 9 7 10 8

第二次交換結束,“探測”繼續。哨兵j繼續向左挪動,他發現了3(比基準數6要小,滿足要求)之後又停了下來。哨兵i繼續向右移動,糟啦!此時哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。說明此時“探測”結束。我們將基準數6和3進行交換。交換之後的序列如下:

3 1 2 5 4 6 9 7 10 8

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

到此第一輪“探測”真正結束。此時以基準數6爲分界點,6左邊的數都小於等於6,6右邊的數都大於等於6。回顧一下剛纔的過程,其實哨兵j的使命就是要找小於基準數的數,而哨兵i的使命就是要找大於基準數的數,直到i和j碰頭爲止。

OK,解釋完畢。現在基準數6已經歸位,它正好處在序列的第6位。此時我們已經將原來的序列,以6爲分界點拆分成了兩個序列,左邊的序列是“3 1 2 5 4”,右邊的序列是“9 7 10 8”。接下來還需要分別處理這兩個序列。因爲6左邊和右邊的序列目前都還是很混亂的。不過不要緊,我們已經掌握了方法,接下來只要模擬剛纔的方法分別處理6左邊和右邊的序列即可。現在先來處理6左邊的序列現吧。

左邊的序列是“3 1 2 5 4”。請將這個序列以3爲基準數進行調整,使得3左邊的數都小於等於3,3右邊的數都大於等於3。好了開始動筆吧

如果你模擬的沒有錯,調整完畢之後的序列的順序應該是:

2 1 3 5 4

OK,現在3已經歸位。接下來需要處理3左邊的序列“2 1”和右邊的序列“5 4”。對序列“2 1”以2爲基準數進行調整,處理完畢之後的序列爲“1 2”,到此2已經歸位。序列“1”只有一個數,也不需要進行任何處理。至此我們對序列“2 1”已全部處理完畢,得到序列是“1 2”。序列“5 4”的處理也仿照此方法,最後得到的序列如下:

1 2 3 4 5 6 9 7 10 8

對於序列“9 7 10 8”也模擬剛纔的過程,直到不可拆分出新的子序列爲止。最終將會得到這樣的序列,如下

1 2 3 4 5 6 7 8 9 10

到此,排序完全結束。細心的同學可能已經發現,快速排序的每一輪處理其實就是將這一輪的基準數歸位,直到所有的數都歸位爲止,排序就結束了。下面上個霸氣的圖來描述下整個算法的處理過程。

快速排序模板:

import java.util.Scanner;

public class Main3 {

	static long[] arr = new long[100003];

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for (int i = 1; i <= n; i++) {
			arr[i] = sc.nextInt();
		}
		dfs(1, n);
		for (int i = 1; i <= n; i++) {
			System.out.print(arr[i] + " ");
		}
	}

	public static void dfs(int low, int higth) {
		if (higth-low<=10) {
			return;
		}
		long jj = arr[low];
		int i = low;// i = low+1;wa
		int j = higth;
		while (i < j) {

			while (arr[j] >= jj & i < j) {
				j--;
			}

			while (arr[i] <= jj & i < j) {
				i++;
			}

			if (i < j) {
				long temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}

		}

		long temp = arr[j];
		arr[j] = arr[low];
		arr[low] = temp;
		dfs(low, j - 1);
		dfs(j + 1, higth);

	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章