大话算法-排序-快速排序

快速排序是一种划分交换排序
基本思想是:
  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))
原文地址:https://www.cnblogs.com/imlifelong/p/10804910.html