zoukankan      html  css  js  c++  java
  • 大话算法-排序-快速排序

    快速排序是一种划分交换排序
    基本思想是:
      1.先从数列中取出一个数作为基准数,一般是第一个数。
      2.将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
      3.再对左右区间重复第二步,直到各区间只有一个数。
    若序列基本有序时,蜕变成冒泡排序,最坏情况是已经排好序
    平均时间复杂度O(nlogn)

    快速排序采用“分而治之、各个击破”的观念,此为原地(In-place)分割版本。

    快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

    步骤为:

      1、从数列中挑出一个元素,称为“基准”(pivot),

      2、重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分割结束之后,该基准就处于数列的中间位置。这个称为分割(partition)操作。
      3、递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
      4、递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

    def partaion(data, left, right):
        less = left - 1 #小区域是从列表初始位置前一位开始
        more = right   #大区域是从列表末尾位置开始,因为末尾位置的数是分隔值,可以视为末尾位置无值
    
        # 遍历整个待定区域  left < 待定区域 < more
        while left < more:
            # data[right] 是选择的那个比较项
            # 如果数 小于 比较项,小于区向右移动一位
            if data[left] < data[right]:
                less += 1
                data[left], data[less] = data[less], data[left]
                left += 1
            # 如果数 大于 比较项,大于区向左移动一位
            elif data[left] > data[right]:
                more -= 1
                data[left], data[more] = data[more], data[left]
            # 如果等于比较项 直接跳过
            else:
                left += 1
        # 整个列表分隔完后,此时left已经来到大区域的第一个位置(等于区 < left 大于区域),和末尾值交换(末尾值是分隔值)
        data[more], data[right] = data[right], data[more]
        # 此时返回小于区域的末尾边界 和大于区域的开始边界
        return less, more+1
    
    def sort(data, left, right):
        # 如果列表为空或者,所需区域不存在,则返回
        if not data or left > right:
            return
        # 随机选择一位作为分界点,将整个排序过程变成时间复杂度的期望值
        index = random.randint(left, right)
        # 交换到末尾,节省一个变量
        data[right], data[index] = data[right], data[index]
        
        # 将列表的数按分隔值分开
        mid = partaion(data, left, right)
        # 递归排序分隔值左边的列表
        sort(data, left, mid[0])
        # 递归排序分隔值右边的列表
        sort(data, mid[1], right)
        
        return data
    
    
    if __name__ == '__main__':
        a = [5, 3, 4, 2, 6, 1, 1, 7, 8, 5, 9, 5, 5, 6, 5]
        a = [-1, -1, 0, -3, -99, 9, 11, 2, 5, 0]
        a = [27, 13, 30, 14, 11, 11,13,13, 5,  6, 16, 18, 7, 17, 5,11,13]
        print(sort(a, 0, len(a)-1))
  • 相关阅读:
    java,jenkins
    docker compose,link,Odoo
    nginx,docker反向代理
    centos7上安装docker-ce社区版
    Install Rancher server
    docker公司测试环境搭建总结
    ansible+docker
    桥接物理网卡,pipwork指定ip,外网连接,研究salt+docker
    20170605
    20170602
  • 原文地址:https://www.cnblogs.com/imlifelong/p/10804910.html
Copyright © 2011-2022 走看看