3.快速排序

在快速排序之前,有一个 D&C 的概念, 即 divede and conquer(分而治之)。具体什么意思呢,就是说可以把一个问题不断划分成小问题,如果划分到最后的小问题很容易解决,那么划分出来的问题都可以这样做,从而这个问题也解决了。

现在的问题是,对一个数组进行排序,可以先想一下,什么情况下数组不用排序,要么这个数组是一个空数组,要么这个数组只有一个数字。那什么情况下数组排序最简单呢,就是数组只含有两个数字,只需要对这两个数字比较大小,然后进行位置变换就可以了。那么现在小问题的解决方案已经有了,现在要做的就是把不是一下子可以解决的大问题划分成一下子就可以解决的小问题。

在快速排序时,按照这个思路,可以先找一个基准值,数组中比这个基准值小的就放在它的左边,否则放在右边。这样最开始的一个数组就变成了一个基准值加上比它小的子数组和比它大的子数组,接下来可以对这两个子数组按照这个方式继续进行划分(递归条件),直到最后子数组中只有一个数字为止(基线条件)。

def quick_sort(array):
    if len(array) < 2:
        return array
    else:
        base_value = array[0]  # 这里选择第一个值作为基准值
        less = [v for v in array[1:] if v <= base_value]
        greater = [v for v in array[1:] if v > base_value]
        return quick_sort(less) + [base_value] + quick_sort(greater)
    
print(quick_sort([1, 3, 6, 2, 5, 4]))

>>>
[1, 2, 3, 4, 5, 6]

这里每次选择基准值时都是把第一个值作为基准值,这样有一个坏处就是,如果这个数组是升序的,那么递归层次最深,效率也最低。这时候算法的运行时间为 O(n2)。而最好的情况是每次选择的值都在中间,两边的子数组等长,这样递归层次最浅,算法的运行时间为 O(nlogn)。在使用时,为了使平均运行时间等同于最佳算法时间,可以使用的方法是每次随机取基准值。

你可能感兴趣的:(3.快速排序)