標籤:style blog color java io strong for ar
快速排序中的演算法思想
1. 分治思想
分治法的基本思想是:將原問題分解為若干個規模更小但結構與原問題相似的子問題。遞迴地解這些子問題,然後將這些子問題的解組合為原問題的解。
我們可以利用分治思想將雜亂無序的數組Arr[p,,r]分為以下幾個步驟
1.分解:
在數組Arr[p,,r]中找出主元x,並且依據這個x對原始的數組進行分解成兩個數組Arr[p,,,q - 1]和Arr[q + 1,,r]是的任何一個屬於Arr[p,,,q - 1]的元素都要小於Arr[q]
任何一個屬於Arr[q + 1,,r]的元素都要大於Arr[q]
2.進行遞迴求解:
通過遞迴調用快速排序對子數組Arr[p,,,q - 1]和Arr[q + 1,,r]進行排序
3.組合
因為快速排序是基於原址排序的,所以不需要進行合併作業,也就是說此時的數組已經排好序了
代碼實現:
虛擬碼:
quickSort(A, p, r) if p < r q = partition(A, p, r) quickSort(A, p, q - 1) quickSort(A, q + 1, r)
在這裡呢,為了排序一個數組的全部元素,初始調用的是A(A, 0, A.length)
其實在數組的分解中最終要的就是他的partition部分,這也是快速排序的關鍵所在
Go語言的實現:
package mainimport "fmt"func partition(A []int, p int, r int) int {x := A[r-1]i := p - 1for j := p; j < r-1; j++ {if A[j] <= x {i += 1A[i], A[j] = A[j], A[i]}}A[i+1], A[r-1] = A[r-1], A[i+1]return i + 1}func quickSort(A []int, p int, r int) {if p < r {q := partition(A, p, r)fmt.Println(q)quickSort(A, p, q-1)quickSort(A, q+1, r)}}func main() {arr := []int{2, 8, 7, 1, 3, 5, 6, 4}quickSort(arr, 0, len(arr))for _, v := range arr {fmt.Println(v)}}
快速排序的效能
在快速排序中,它的已耗用時間取決於他是否是劃分平衡的,如果劃分的平衡那麼他的時間複雜度和歸併排序一樣是nlog2(n),當劃分不平衡時,時間複雜度就和插入排序一樣是O(n^2),但是當元素的個數大於20,快速排序的效能遠遠好于歸並和堆排序(在劃分平衡的情況下),這裡也就是說他的平均效能是十分的優越的
1.最壞的情況:
當數組A[p,,r]在劃分時產生了這麼兩個數組,他們的元素個數分別是A.length - 1和0,可想而知,當演算法每一次遞迴調用時,都出現了這樣極為不平衡的情況,那麼劃分的時間複雜度就是Θ(n),由於對於一個數組元素個數為0的數組的遞迴調用,就會直接返回,因此T(0) = Θ(1)
最終演算法已耗用時間為:T(n) = T(n - 1) + Θ(n)
2.最好情況的劃分:
其實在快速排序中一般或者絕大多數排序都是更加的接近於最好的情況,而不是最糟糕的情況,
在快速排序中,只要你劃分的比例是常數比例,演算法的時間複雜度總是O(nlogn),也就是說,哪怕你劃分的結果是9999:1,時間複雜度還是O(nlogn);
說明:
本篇屬於原創,允許轉載,但是請標明原始的串連!!
參考:《演算法導論》