排序演算法——快速排序

鴨脖發表於2013-05-05

快速排序是對氣泡排序的一種改進。為什麼這麼說呢?想一下氣泡排序,我們是把輕的往上面冒,參照的是某一個位置上的,這個位置是我們認為規定的從底部依次往上數。而快速排序的這個位置是我們隨機選擇的或者選中間,選取方法也是一種演算法,演算法書上有介紹。然後拿這個位置上的元素作參照,比他大就往下沉,比他小就往上升。然後再交換元素。所以它也是基於交換元素的。然後它還是遞迴的。


說到這個演算法我覺得我應該想到百度2011年的筆試題,其中有一個排石頭的題目,只有天平,而不能計算出石頭的實際重量,只能通過比較來排序。那麼這個就是一個快速排序的典例。


快速排序的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。


演算法的時間複雜度是:快速排序每次將待排序陣列分為兩個部分,在理想狀況下,每一次都將待排序陣列劃分成等長兩個部分,則需要logn次劃分。

而在最壞情況下,即陣列已經有序或大致有序的情況下,每次劃分只能減少一個元素,快速排序將不幸退化為氣泡排序,所以快速排序時間複雜度下界為O(nlogn),最壞情況為O(n^2)。在實際應用中,快速排序的平均時間複雜度為O(nlogn)。

下面是我寫的一個程式:
void quickSort(int* a,int left,int right){
	if(left>=right)
		return;
	int i = left;
	int j = right;
	int mid = (left+right)/2;
	int key = a[mid];//隨機選取中間元素
	while(1){//從兩邊選取可以交換的元素並且實現交換
		while(a[j]>key)
			j--;
		while(a[i]<key)//i和j的值在這裡有可能重合,所以不能加上=
			i++;
		if(i>=j)
			break;
		//選取交換元素的程式停下來然後進行交換
		int tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}
	//遞迴呼叫
	quickSort(a,left,j);//思考為何這裡選j
	quickSort(a,j+1,right);
}

相關文章