1. 程式人生 > >使用java實現快速排序(我認為是最簡單最容易理解的版本)

使用java實現快速排序(我認為是最簡單最容易理解的版本)

一切都在程式碼和註釋之中。複製貼上就能跑,邊跑邊看才是最愉快的。

所以,話不多說,放碼過來。

 

public class QuickSort {

	public static void main(String[] args) {
		int x[]={6,1,2,7,9,100,100,4,5,10,8}; //i = 0, j = 10 
		quickSort(x, 0, x.length-1);
		for (int i = 0; i < x.length; i++) {
				System.out.print(x[i] + " ");
		}
	}
	//快排的核心是: 分治法
	//步驟:
	//1.選中一個基準值
	//2.一次排序後,基準值的右邊都大於基準值,基準值的左邊都小於基準值
	//3.一次排序完成後,一個數組就分成了兩份,然後使用遞迴對這兩份繼續排序,直到每一份中只剩一個值
	//4.進行排序的那一份只剩一個值時,出遞迴。
	public static void quickSort(int[] arr, int low, int high) {
		
		if(low >= high) {
			return;
		}
		//選擇一個基準值,為了簡單,我直接使用了陣列中的第一個值來作為基準值
		int middle = arr[low];
		
		//為什麼要用left和right來表示 low 和 high呢?
		//因為low和high要用在最後的遞迴呼叫,所以不能更改這兩個變數的值。
		
		//宣告一個從左往右找值的哨兵
		int left = low;
		//宣告一個從右往左找值的哨兵
		int right = high;
		
		while (left < right) {
			
			//從右往左找比中位數小的值
			while(arr[right] >= middle && left < right) {
				right --;
			}
			//從左往右找比中位數大的數
			while(arr[left] <= middle && left < right) {
				left ++;
			}
			
			//當找到兩個想要的值的時候,進行交換
			if(left < right) {
				int temp = arr[left];
				arr[left] = arr[right];
				arr[right] = temp;
			}
		}
		
		//一個while迴圈之後,left = right ,而且此時arr[left]的值小於middle,因為我們先從右邊開始找的,
		//所以肯定是right-1後碰到的left,如果left經歷過交換的話,arr[left]的值肯定小於middle,
		//沒經歷過交換的話arr[left]的值就是middle,所以把arr[left] 和 middle交換是沒問題的
		arr[low] = arr[left];
		arr[left] = middle;
		quickSort(arr, low, left-1);
		quickSort(arr, left+1, high);
	}
	
	//從右往左找比中位數小的數,這裡要注意使用的是 >= 和 <= 
	//如果不帶=號會陷入一個死迴圈,為什麼會陷入死迴圈呢? 我給大家舉一個栗子
	
	//假設要對這個陣列{100,100,7,10,8}進行快排,而且不使用>= 和 <= 而是使用 > 和 <
	//1.先從右往左找一個 不滿足 >middle的值,也就是 <=middle的值,找到了arr[1] 也就是100
	//2.然後從左往右找一個不滿足 < middle的值,也就是 >=middle的值,找到了arr[0] 也就是 100
	//3.兩者進行交換後,再從右往左找<=middle的值,right-1後就與left相等了,下面交換中位數的位置
	//4.發現中位數的位置是arr[0],改變前後無異,然後遞迴繼續排序左邊的和右邊的,
	//可是左邊為空,右邊就一直都是死迴圈。