1. 程式人生 > >演算法分析——分治思想之快速排序

演算法分析——分治思想之快速排序

優化一個演算法的最根本的原理就是減少演算法的基本操作。

分治法的設計思想是,將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。

於是,在快速排序中,我們通過分割陣列的思路來將大問題分割成小規模的問題,與二分搜尋法類似的是,在二分法

中,我們需要進行的操作是搜尋,是在已經排好序的基礎上通過一分為二來減少搜尋範圍,降低時間複雜度,二分搜

索中通過尋找中位數,將陣列分為左右兩邊,通過與中位數的比較確定待查詢數所在的範圍,即,我們在判斷是否中

位數與待查詢數的大小的同時,還利用判斷的結果,將搜尋的範圍縮小,這就與最基本的遍歷法中僅僅比較是否相等

有了很大的差距,換句話講,就是在二分搜尋中,我們通過一次比較進行了兩種操作,而在傳統的遍歷中,我們通過

一次比較僅僅只進行一種操作。於是,在排序中,我們是否也可以考慮這種思路。傳統的氣泡排序中,我們僅僅在一

個數與其他數的比較時確定了一個數的位置(這裡寫的有點難理解的感覺),我們在進行比較的同時是否能仿照二分

搜尋法一般,比較的同時縮小排序的範圍,即我們通過選取一個基準元素將帶排序陣列劃分為兩個陣列,在基準元素

與陣列元素進行比較的同時,將大於基準元素的數放到陣列的右側,小於基準的數放到陣列左側,在通過同樣的思路

對被劃分而成兩個個子問題進行相同的操作,直到最終子問題的大小等於3。

下面就是相關的實現步驟:

1.分解:以a[p]為基準元素將a[p:r]劃分為三段a[p:q-1],a[q+1:r]使得a[p:q-1]中任何元素小於等於a[q],a[q+1]中任何元素

大於等於a[q]下標q在劃分過程中確定

2.遞迴求解:通過遞迴呼叫快速排序演算法,分別對a[p:q-1]和a[q+1]進行排序

3:合併:由於對a[p:q-1]和a[q+1:r]的排序是就地進行的所以a[p:q-1]和a[q+1:r]都已排好的序後不需要執行任何計算,

就已排好序.

void Algorithm::qSort(int a[],int left,int right)
{
	if(left<right)
	{
		int middle=partition(a,left,right);
		qSort(a,left,middle-1);
		qSort(a,middle+1,right);
	}
}
int Algorithm::partition(int a[],int left,int right)
{
	int first=left+1;
	int	last=right;
	int number=a[left];
	int i=0;
	while(true)
	{
		while(a[first]<number&&first<=right)
		{
			first++;
		}
		while(a[last]>number)
		{
			last--;
		}
		if(first>=last)
		{
			break;
		}
		else
		{
			int temp=0;
			temp=a[last];
			a[last]=a[first];
			a[first]=temp;
		}
	}
	a[left]=a[last];
	a[last]=number;
	return last;
}