两种快速排序解析--python

快速排序的主要思想就是分而治之,递归将序列用主元分为两个子序列然后排序. 

根据维基百科的描述,快速排序有两种:

第一种是由Lomuto提出的,  为in-place交换;将序列最后一个元素选为主元。两个扫描标签从左边开始,当array[ j ]大于主元时,j继续扫描;当array[ j ]小于主元时,交换array[ i+1 ]和array[ j ].

两种快速排序解析--python_第1张图片

首先,主元为最后一个元素 4,array[j] = 2,小于主元,所以交换array[i+1]和array[ j ]的值。因为 i+1 和 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[r]
    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 ].

两种快速排序解析--python_第2张图片

     首先, 主元为第一个元素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

 

你可能感兴趣的:(数据结构,Python)