1. 程式人生 > >兩種快速排序解析

兩種快速排序解析

快速排序的主要思想就是分而治之,遞迴將序列用主元分為兩個子序列然後排序. 

根據維基百科的描述,快速排序有兩種:

第一種是由Lomuto提出的,  為in-place交換;將序列最後一個元素選為主元。兩個掃描標籤從左邊開始,當array[ j ]大於主元時,j繼續掃描;當array[ j ]小於主元時,交換array[ i+1 ]和array[ j ].

首先,主元為最後一個元素 4,array[j] = 2,小於主元,所以交換array[i+1]和array[ j ]的值。因為i和j        都指向同一個index所以沒有改變 。j繼續向前移動

    array[ j ] = 8 > 4, 所以不用交換,i的位置也不會移動。j繼續向前移動。

    array[ j ] = 7 > 4, 所以不用交換,i的位置依舊不會移動,j繼續向前移動。

    array[ j ] = 1 < 4, 所以交換array[i+1]和array[ j ]的值,j繼續向前移動。

    array[ j ] = 3 < 4, 所以交換array[i+1]和array[ j ]的值,j繼續向前移動。

    array[ j ] = 5 > 4, 所以不用交換,i的位置也不會移動。j繼續向前移動

    array[ j ] = 6 > 4, 所以不用交換,i的位置也不會移動。j繼續向前移動

    此時j = r,交換array[i+1]和array[ r ]的值就完成了一輪排序。

    

上面為一輪排序,後面遞迴對兩個子序列進行排序 。該演算法保證了i+1到 j-1 之間的序列值永遠比 array[r]的值大,所以當 array[ j ]小於array[r]時,可以將array[i+1]和array[j]進行交換,最後在交換array[i+1] 的值和array[r]的值,這樣就能保證i+1之前的值比array[i+1]的值小,i+1之後的值都比array[i+1]的值大。下面為python程式碼:

## 將序列從小到大排序
def quick_sort(array, lo, r):
    """array:  待排序的序列
       lo: array裡面最小的index
       r: array裡面最大的index
    """
    if lo < hi:
        q = partition(array, lo, r)
        quick_sort(array, lo, q-1)
        quick_sort(array, q+1, r)

def partition(array, lo, r):
    x = array[hi]
    i = lo - 1
    for j in range(lo, r):
        if array[j] <= x:
            i += 1
            array[i], array[j] = array[j], array[i]
    array[i+1], array[r] = array[r], array[i+1]
    return i+1

如果想要從大到小的排序,將array[ j ] <= x 改為array[ j ] >= x 即可。 

第二種是由Hoare提出的。將序列的第一個元素作為主元。從左右兩個方向開始對array排序,j從右邊開始找小於主元的值,找到後將array[ j ]的值賦給array[ i ];  i從左邊開始找大於主元的值,找到後將array[ i ]的值賦給array[ j ].

     首先, 主元為第一個元素6, j從右向左找到array[ j ] =  5 < 6,將它的值賦給array[ i ];

     i從左向右掃描,找到array[ i ] = 8 > 6, 將它的值賦給array[ j ];

     j繼續 從右向左找到array[ j ] =  4 < 6,將它的值賦給array[ i ];

     i繼續從左向右掃描,找到array[ i ] = 7 > 6, 將它的值賦給array[ j ];

      此時 i = j,停止掃描,將主元賦給array [i]

 

上面就完成了一次排序,後面再遞迴對兩個子序列排序即可。下面為python程式碼:

def quick_sort(array, lo, hi):
    if lo < hi:
        p = partition(array, lo, hi)
        # 這裡為p而不是p-1,因為當左邊的序列只有一個主元的時候會出現lo > hi的情況
        quick_sort(array, lo, p)
        quick_sort(array, p+1, hi)

def partition(array, lo, hi):
    x = array[lo]
    i = lo
    j = hi
    while i < j:
        while i < j and array[j] >= x:
            j -= 1
        if i < j:
            array[i] = array[j]
        while i < j and array[i] < x:
            i += 1
        if i < j:
            array[j] = array[i]
    array[i] = x
    return i

   

參考連結:https://blog.csdn.net/v_JULY_v/article/details/6116297