04算法-快速排序(深入分析)

abstract

本文是對快速排序算法的深入分析,主要講解了快速排序算法的基本原理,時間複雜度分析以及如何去改進的快排算法,本文提供快排的僞代碼,以及用Golang實現的具體代碼。
這裏補充一下一般算法設計的思路,首先根據問題分析建模,設計最初版本的代碼,分析代碼的running time,然後找到問題所在,解決問題。這樣的。

the idea of algorithm

快速排序算法是典型的使用分治法設計的算法,算法主要分爲:
dividekey這是快排的關鍵,
conquer:recursive sort 2 part
combine:這部分不做什麼,因爲快排不像merge sort沒有消耗而外的空間
實現快排的關鍵就是在線性的時間,完成對子數組的分割

common quick sorting

我們先開快排的僞代碼

//其中分割函數
partition(A, p, q)
	X <- A[p]  
	curr <- p
	for j <- p+1 to q
		do if A[j] <= X 
			then curr <- curr+1
				exch A[curr] A[j]
	exch A[p] A[curr]
	return curr

//對於combine部分
quickSort(A, p, q)
	if p < q then
		mid <- partion(A, p, q)
		quickSort(A, p, mid-1)
		quickSort(A, mid+1, q)

使用GO實現的代碼如圖所示:

func partition(A []int, left, right int)  int{
	midNum := A[left]
	startFLag := left
	for i := left+1; i <=right; i++{
		if A[i] <= midNum{
			startFLag++
			A[i], A[startFLag] = A[startFLag], A[i]
		}
	}
	A[left], A[startFLag] = A[startFLag], A[left]
	return startFLag
}

func QuickSort(A []int, left

 - [ ] List item

, right int)  {
	if right > left{
		mid := partition(A, left, right)
		QuickSort(A, left, mid-1)
		QuickSort(A, mid+1, right)
	}
}

下面說一下時間複雜度

上述算法的運行時間是取決於輸入數據的情況
我們來考慮==最好的情況(卵用沒有)==假設每次選擇的數據都會置換到當前數據段的中心,那遞歸公式爲T(n)=2T(n/2)+Θ(n)T(n)= 2T(n/2)+\Theta(n) 所以其running time爲Θ(nlgn)\Theta(nlgn)
我們考慮最壞的情況,每次置換過後的位置都是left+1left+1,那遞歸公式就是T(n)=T(0)+T(n1)+Θ(n)T(n)=T(0)+T(n-1)+\Theta(n)所以其running time爲Θ(n2)\Theta(n^2)
對於一個普通的情況,一般會偏向於好的情況一點,但是這種程度的算法是達不到實際使用需求的。

rand quick sorting

考慮到上面的問題,我們需要改進快速排序算法,其中最容易想到的是:將挑選的元素隨機話。

func randPartition(A []int, left, right int)  int{
	key := int(rand.Int63n(int64(right-left))) + left
	A[left], A[key] = A[key], A[left]

	midNum := A[left]
	startFLag := left
	for i := left+1; i <=right; i++{
		if A[i] <= midNum{
			startFLag++
			A[i], A[startFLag] = A[startFLag], A[i]
		}
	}
	A[left], A[startFLag] = A[startFLag], A[left]
	return startFLag
}

其中隨機話處理的代碼如上所示。這樣處理能夠帶來什麼樣的好處了。這樣能保證算法的running time<=anlgnrunning\ time <= anlgn
下面是純數學分析,如果不想了解太深,完全沒有必要看
在證明上面的結論上,需要使用到一個定律k=2n1klgk<=12n2lgn18n2\sum_{k=2}^{n-1}klgk<={\frac 12}n^2lgn-{\frac 18}n^2
首先定義了一個這樣的概率分佈函數xk=1(if there is a partition k:nk1) and xk=0(other)x_k=1(if\ there\ is\ a\ partition\ k:n-k-1)\ and\ x_k = 0(other)
對於T(n)這個函數,它的表現形式就可以寫成T(n)=k=2n1xk{T(k)+T(nk1)+Θ(n)}T(n)=\sum_{k=2}^{n-1}{x_k\{T(k)+T(n-k-1)+\Theta(n)\}}式中可以不考慮k=0和1的情況。
根據獨立分佈的特性可以推導爲E(T(n))=2nk=2n1{T(k)+Θ(n)}E(T(n))={\frac 2n}\sum_{k=2}^{n-1}{\{T(k)+\Theta(n)\}}
E(T(n))=2nk=2n1T(k)+Θ(n)E(T(n))={\frac 2n}\sum_{k=2}^{n-1}T(k)+\Theta(n)
再用代換法加上上面給出的定理來證明:
假設<=2nk=2n1aklgk+Θ(n)<={\frac 2n}\sum_{k=2}^{n-1}aklgk+\Theta(n)
<=2an(12n2lgn18n2)+Θ(n)<={\frac {2a}n}({\frac 12}n^2lgn-{\frac 18}n^2)+\Theta(n)
<=anlgna4n+Θ(n)<=anlgn -{\frac a4}n+\Theta(n)
so when a4n>Θ(n){\frac a4}n>\Theta(n), the next is proved
<=anlgn<=anlgn

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