快速排序及其随机化版本

快速排序思想:

  1.从数组中取出一个元素记为i,将数组划分为两个部分,前半部分所有元素比该元素小,后半部分的所有元素比该元素大。

  2.将i放置在两部分之间,对前半部分与后半部分递归进行第一步直至数组长度为1,排序完成。

快速排序时间复杂度:

  当第一步划分的两个部分其中一个部分包含了n-1个元素,另一部分包含0个元素时为最坏情况。如果每一层递归上的划分都是最大程度不平衡的,此时快速排序的时间复杂度为Θ(n2)。

  当第一步划分的两个部分其中一个部分包含了n/2个元素,另一部分包含n/2-1个元素时为最好情况。如果每一层递归上的划分都是最大程度平衡的,此时快速排序的时间复杂度为Θ(nlgn)。

  快速排序的平均运行时间更接近于最好情况,只要划分是常数比例的,算法的运行时间总是O(nlgn)。

快速排序代码示例:

import random

def quick_sort(a,i,j):
    if i < j:
        q = partition(a,i,j)
        quick_sort(a,i,q-1)
        quick_sort(a,q+1,j)
    
def partition(a,i,j):
    ret = i - 1
    for k in range(j-i):
        if a[i+k] < a[j]:
            ret += 1
            tmp = a[i+k]
            a[i+k] = a[ret]
            a[ret] = tmp
    ret += 1
    tmp = a[j]
    a[j] = a[ret]
    a[ret] = tmp
    return ret

def main(args):
    a = []
    for i in range(100):
        a.append(random.randint(1,100))
    print(a)
    quick_sort(a,0,len(a)-1)
    print(a)
    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

以上代码每次都用最后一个元素对数组进行划分。可以在排序中引入随机性,即从数组的随机位置挑选一个元素来进行划分,即可获得更好的期望性能,代码如下:

import random

def quick_sort(a,i,j):
    if i < j:
        q = randomized_partition(a,i,j)
        quick_sort(a,i,q-1)
        quick_sort(a,q+1,j)
    
def randomized_partition(a,i,j):
    ret = i - 1
    #引入随机性
    int_random = random.randint(i,j)
    tmp = a[j]
    a[j] = a[int_random]
    a[int_random] = a[j]
    for k in range(j-i):
        if a[i+k] < a[j]:
            ret += 1
            tmp = a[i+k]
            a[i+k] = a[ret]
            a[ret] = tmp
    ret += 1
    tmp = a[j]
    a[j] = a[ret]
    a[ret] = tmp
    return ret

def main(args):
    a = []
    for i in range(100):
        a.append(random.randint(1,100))
    print(a)
    quick_sort(a,0,len(a)-1)
    print(a)
    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

 

posted @ 2018-10-30 19:30  东东欧尼酱  阅读(365)  评论(0编辑  收藏  举报