天天看點

解析快速排序算法快速排序算法

快速排序算法

快速排序采用了分治法:我自己随機給出一個數組為例arr = {4,8,6,7,2,0,9,1,3,5}
           

    a.首先標明數組的第一個數作為基準數,即arr[0] = 4為初始基準數。

    b.然後給出兩個初始參數i和j分别指向arr[1]和arr[arr.length-1],即初始化i=1;j=arr.length-1。

    c.指向完成後j先從右向左移動,即j- -,直到找到一個數小于初始基準數arr[0] = 4。

    d.然後i開始從左向右移動,即i++,直到找到一個數大于初始基準數arr[0] = 4。

    e.此時并不能急于交換arr[i]和arr[j]的值,而是先要判斷j<=i是否成立,若成立則證明arr[0]右側的數值都比arr[0]大,這時就需要重新劃基準數(随機在數組重找一個)············重複上述過程(在此沒有出現這種情況),若j>i,則arr[i]和arr[j]交換位置:

解析快速排序算法快速排序算法

    此時數組變為:4 3 6 7 2 0 9 1 8 5

    f.重複上述c d e過程。值得注意的是,i和j從交換完成的位置繼續分别向右向左行進,并不是從初始位置行進。

解析快速排序算法快速排序算法

    此時數組變為:4 3 1 7 2 0 9 6 8 5

    g.以此類推:

解析快速排序算法快速排序算法

    此時數組變為:4 3 1 0 2 7 9 6 8 5

解析快速排序算法快速排序算法

    到此,發現i = j,這可如何是好?莫慌,看上述e步驟,該arr[0]和arr[j]交換的時候了,數組變為:2 3 1 0 4 7 9 6 8 5

    到這裡,我們發現4左邊的數全都比4小,右邊的數全都比4大,這就是典型的分治法,分開治理嘛。

    h.我們此時得到的數組就可以分開治理啦,4左邊的數和右邊的數我們可以分别看做一個數組,然後結合遞歸的思想将數組arrLeft = {2,3,1,0}重複上述步驟,同樣的結合遞歸的思想将arrRight = {7,9,6,8,5}重複上述過程,這樣最終就會的道一個完整的有序數組。

解析快速排序算法快速排序算法

-----有關快速排序的時間複雜度的問題:快速排序運用了遞歸的思想,遞歸的時間複雜度為:T[n]=aT[n/b]+f(n) 。快排的時間複雜度有最優性和最差性,這和選取的初始基準數有關。

①最優情況下的時間複雜度:

    快速排序最優的情況就是每一次取到的元素都剛好平分整個數組,此時的時間複雜度公式則為:T[n] = 2T[n/2] + f(n);T[n/2]為平分後的子數組的時間複雜度,f[n] 為平分這個數組時所花的時間。

    m遞歸之後,n = n/( 2^(m-1) ) = 2^m T[1] + mn

得到T[n/ (2^m) ] = T[1] —》 n = 2^m —》 m = logn

    T[n] = 2^m T[1] + mn ;其中m = logn

    是以T[n] = 2^(logn) T[1] + nlogn = n T[1] + nlogn = n + nlogn(其中n為元素個數)

    當n>=2是nlogn>>n可記為T[n] = nlogn

    是以最優快速排序的時間複雜度為O(nlogn)

②最差情況下的時間複雜度:

    最差的情況下發現一個有意思的事情,排序方式竟然就是冒泡排序!!!

    T[n] = n*(n+1) = n^2+n

    此時時間複雜度為O(n^2)

-----有關快速排序的空間複雜度的問題:由于運用了遞歸的思想,真正消耗空間的其實是遞歸,快速排序使用的空間僅僅是一次即O(1)。

①最優情況下的空間複雜度:每次都均分數組O(logn)

②最差情況下的時間複雜度:冒泡排序O(n)

繼續閱讀