排序算法的C語言實現-快速排序

快速排序是在實踐中最快的已知排序算法,它的平均運行時間是O(NlogN),該算法之所以特別的快,主要是由於非常精煉和高度優化的內部循環。它的最壞情形的性能爲N^2.

快速排序由下列簡單的四步組成:

1.如果S中元素個數是01,則返回。

2.取S中任以元素V,稱之爲樞紐元

3.將S分成倆個不相交的集合,前一個元素都小於V,後一個元素都大於V

4.返回quicksortS1)後,加上V,再加上quicksortS2);

如何選取樞紐元?

有一種安全的方法是隨機選取樞紐元,但是產生隨機數的代價是很昂貴的,減少不了算法其餘部分的平均運行時間。

這裏有種方法叫三數中值分割法,樞紐元最好的值是數組的中值,也就是第N/2個最大的數,但是這很難算出,而且嚴重減慢了算法的速度。那麼退而求其次,我們用數組左端,中心,右端位置的中值來做樞紐元。

快速排序的交換策略是這樣的:在開始之前將樞紐元和最後一個元素交換,讓樞紐元離開要被排序的數組,因爲數組排序完後,樞紐元的位置是一定的。i從第一個元素開始,j從倒數第二個元素開始,當i在j左邊時,我們將i右移,移過那些小於樞紐元的元素,將j右移,移過那些大於樞紐元的元素。當i,j停止時,i指向一個大於樞紐元的元素,而j指向一個小於樞紐元的元素,這樣做的效果最終是所有小於樞紐元的元素都在樞紐元左邊,大於樞紐元的元素都在它的右邊。從而達到了排序的意願。




void quickSort(int a[],int length)
{
	Qsort(a,0,length-1);
}

int median3(int a[],int left,int right)	//獲得樞紐元,使用三數中值法
{
	int center=(left+right)/2;
	
	if(a[left]>a[center])
		swap(&a[left],&a[center]);
	if(a[left]>a[right])
		swap(&a[left],&a[right]);
	if(a[center]>a[right])
		swap(&a[center],&a[right]);
	swap(&a[center],&a[right-1]);	//將樞紐元放到數組最後
	return a[right-1];
}

void Qsort(int a[],int left,int right)
{
	int i,j;
	int pivot;
	
	if((left+3)<=right)
	{
		pivot=median3(a,left,right);
		i=left,j=right-1;
		for(;;)
		{
			while(a[++i]<pivot){}	//因爲第一次是a[i]小於pivot,a[j]是大於pivot,所以用++i
			while(a[--j]>pivot){}
			if(i<j)
				swap(&a[i],&a[j]);	//出現等於的情況,交換,平均分配到子數組中
			else
				break;
		}
		swap(&a[i],&a[right-1]);
		Qsort(a,left,i-1);	//在i的位置之前,所有的元素都小於它,在i之後,所有的元素都大於它,所以A[i]的位置不需要變
		Qsort(a,i+1,right);
	}
	else	//當數組很小的時候,只做插入排序,從而退出遞歸,不需要等到數組長度等於1的時候,因爲對於小數組來說,插入排序好過快速排序
		insertionSort(a+left,right-left+1);	//插入排序例程在前面的文章中已經實現了
}


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