排序算法——快速排序(快排)

快速排序

(一)概念及實現

思想:分治策略。

快速排序的原理:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比基準數據小,另外一部分的所有數據都要比基準數據大,然後再按此方法對這兩部分數據分別進行快速排序。

"保證列表的前半部分都小於後半部分"就使得前半部分的任何一個數從此以後都不再跟後半部分的數進行比較了,大大減少了數字間的比較次數。


 

具體如下(實現爲升序)

設數組爲a[0…n]。

1.        數組中找一個元素做爲基準(temp),通常選數組的第一個數。

2.        對數組進行分區操作。使基準元素左邊的值都小於temp,基準元素右邊的值都大於等於temp。

3.        將temp值調整到分區後的正確位置。

4.        將基準兩邊的分區序列,分別進行步驟1~3。(遞歸)

5.        重複步驟1~4,直到排序完成。


以下是代碼的算法思路: p代表傳入數組的第一個元素的下標,r代表數組最後一個元素的下標

排序子數組 a[ p : r ],步驟如下:
 (1)分解:以 a[ p ] 爲基準元素將 a[ p : r ] 分成 3 段: a[ p : q - 1 ]、 a[ q ]、 a[ q + 1 : r ]。滿足條件: a[ p : q - 1 ] 中任何一個元素 <= a[ q ]; a[ q + 1 : r ] 中任何一個元素 >= a[ q ]。下標 q 在劃分過程中確定。

 ( 2)遞歸求解:通過遞歸調用快速排序算法分別對 a[ p : q - 1 ] 和 a[ q + 1 : r ] 進行排序。
(3)合併:對 a[ p : q - 1 ] 和 a[ q + 1 : r ] 的排序在各自的範圍內進行,因此排好序後不需任何運算整個數組 a[ p : r ] 即完成排序。



上述算法的關鍵是函數 Partition ,其功能是以一個確定的基準元素 a[ p ] 對子數組 a[ p : r ] 進行劃分,它是整個排序算法的關鍵。(這個算法思想可以用在很多算法思想上)

Partition例圖:




代碼如下:

<span style="font-size:18px;color:#333333;">#include<stdio.h>
#include<stdlib.h>

void swap(int *x,int *y)        //交換函數
{
	int temp;
	temp=*x;
	*x=*y;
	*y=temp;
}



int Partition(int a[],int low,int high)     
{
	int temp=a[low];
	int i=low;
	int j=high;
	while(i<j)
	{	
		while(a[j]>temp&&i<j)
			j--;
		if(i<j)
		{
			swap(&a[i],&a[j]);
			i++;
		}
		while(a[i]<temp&&i<j)
			i++;
		if(i<j)
		{
			swap(&a[i],&a[j]);
			j--;
		}
	}
	return i;
}

void QuickSort(int a[],int p,int r)
{
	if(p<r)
	{
		int q=Partition(a,p,r);
		QuickSort(a,p,q-1);     //左半邊排序
		QuickSort(a,q+1,r);		//右半邊排序
	}
}




int main()
{
	int i;
	int a[10]={45,32,67,54,34,32,21,25,67,98};
	QuickSort(a,0,9);
	for(i=0;i<=9;i++)
		printf("%d\n",a[i]);
	return 0;
}</span>
不知道爲什麼編譯時間好長。待我再研究下

(二)算法複雜度

1.        時間複雜度:O(nlog2n)

快速排序耗時的操作有:比較 + 交換(每次交換兩次賦值)。時間複雜度如下:

1)        最好情況:選擇的基準值剛好是中間值,分區後兩分區包含元素個數接近相等。因爲,總共經過x次分區,根據2^x<=n得出x=log2n,每次分區需用n-1個元素與基準比較。所以O(nlog2n)

2)        最壞情況:

最壞情況是樞紐元爲最大或者最小數字,那麼所有數都劃分到一個序列去了 時間複雜度爲O(n^2)

3)        漸進時間複雜度(平均時間複雜度):O(nlog2n)

2.        空間複雜度:O(1)

從實現原理可知,快速排序是在原輸入數組上進行比較分區的(稱“就地排序”),所需開闢的輔助空間跟輸入數組規模無關,所以空間複雜度爲:O(1)

 

(三)穩定性

快速是不穩定的,會改變相同元素的相對順序。


(四)優化改進

當每次分區後,兩個分區的元素個數相近時,效率最高。所以找一個比較有代表性的基準值就是關鍵。通常會採取如下方式:

1.        選取分區的第一個元素做爲基準值。這種方式在分區基本有序情況下會分區不均。

2.        隨機快排:每次分區的基準值是該分區的隨機元素,這樣就避免了有序導致的分佈不均的問題

3.        平衡快排:取開頭、結尾、中間3個數據,通過比較選出其中的中值。




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