zoukankan      html  css  js  c++  java
  • 算法 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

    下回见

  • 相关阅读:
    [转]MySql 5.7关键字和保留字-附表
    [转]超链接标签简单的几个样式属性
    layui table 前台数字格式保留两位小数,不足补0(mysql 数据库)
    [转]Object.keys()和for in的排序问题
    [转]对form:input标签中的数字进行格式化
    [转]bootstrap table 动态列数
    [转]bootstrap的table插件动态加载表头
    [转]【MyBatis】Decimal映射到实体类出现科学计数法问题
    [转]MySQL函数大全 及用法示例
    [转]mysql update case when和where之间的注意事项
  • 原文地址:https://www.cnblogs.com/lipijin/p/3289529.html
Copyright © 2011-2022 走看看