算法 python实现(三) 快速排序

算法学起来真费劲啊,智商只够捉只鸡的。昨晚没看明白就没电了,过两天要考虑偷电了...

今天看看快速排序,有一个博客写的很好,通俗生动形象,适合我这样的算法大白菜。推荐一下 http://www.cnblogs.com/morewindows/category/314533.html 

里面的快排的形象比喻特别到位,我就借花献佛了。

大体情况是这样的:

1. 拿一个数作为基准数(我一般都是拿第一个数,就是a[0]),比这个数小的都放在他的左边,比这个数大的都放在他的右边。这样就分出来了两个小序列。

2. 然后在分出来的两个小数列中再分别进行这样的操作,直到小序列只剩一个数。

下面看看具体怎么做:

这里有一堆数 a = [1,3,4,2,5,0]

1. 首先拿到 x = a[0] 作为基准数,两个指针left,right 分别指向数列的头和尾。把这个基准数挖出来,那现在a[0]这个位置就是一个坑,而且left在指向这个坑。

2. 从right开始,比较a[right] 和 x 大小,按照上面的目的,小的在左大的在右,如果a[right] <= x,那就把a[right]这个数挖出来,填到一开始那个坑里。也就是替换a[left] a[right],注意现在right的位置是一个坑。 然后让left+1,换到left开始找。那如果a[right] > x 那就不动,把right-1 往前继续找比x小的数。直到找到小于x 的数然后然后挖坑,或者当left == right的时候结束,因为left == right 说明left right指向同一个坑,然后就可以把x填进去了。这一次就完事了,分为了两个小序列。

3. 从right那边找到后换到left找。找什么,找满足a[left] > x的数,把它往后挪。道理跟right那边操作是一样的,找到之后挖出来,填进right指向的那个坑里,然后让right -1往前挪,准备下次的找数。注意a[left]被挖出去了,那left就指向了一个坑。等待下次right那边找到合适的数填进来。同样,只要left == right了,就把x填进去,然后结束。序列也就被分为了两个小序列。

有点罗嗦,代码:

#首先写挖坑的操作,挖坑操作只能处理序列成为两个小序列
#至于小序列的从排序是不能自动处理的
#所以一会还要有另一个函数来递归调用挖坑函数
#达到使每一个小序列也进行挖坑操作的目的

#指定序列a,左指针left,右指针right,左右指针表明了排序的区间
#因为在处理小序列的时候,头尾就不再是0 和 len(a)-1 了
def wakeng(a, left, right):
    #这个x就是基准数,一般拿头就可以了
    x = a[left]
    #当left right重合时,把x填进这个坑,然后结束本次挖坑操作
    while left < right:
        #开始尾巴找小的往左放
        #这里加了left right条件是因为当序列初始就是排好基准数右边都比他大
        #right都到了left那边,都越界了,right还在自减,这可不行
        while left < right and a[right] > x:
            right -= 1
        #同样的道理,要保证不越界
        if left < right:
            a[left] = a[right]
            left += 1

        #开始从头找大的往右放
        while left < right and a[left] <= x:
            left += 1
        if left < right:
            a[right] = a[left]
            right -= 1
    #把x填进 left 和 right 同时指向的这个坑
    a[left] = x
    #返回当前基准数的位置,作为下次小序列的边界。
    return left

#循环每个小序列的函数,分治
def fenzhi(a, left, right):
    #同样函数结束条件就是left == right
    if left < right:
        #拿到位置
        weizhi = wakeng(a, left, right)
        #分别对两个小序列再分治挖坑
        fenzhi(a,left,weizhi-1)
        fenzhi(a,weizhi+1,right)

a = [123,434,3,44,545,465,43,34,54,676,34,4,5,6]
fenzhi(a, 0, len(a)-1)
print a

下回见

原文地址:https://www.cnblogs.com/lipijin/p/3289529.html