zoukankan      html  css  js  c++  java
  • 《算法图解》之快速排序

    以前一章的递归为基础,讲述“分而治之”,即D&C。重点讲述二分查找的基础——快速排序。

    1 分而治之

    分而治之(divide and conquer, D&C)一种著名的递归式问题解决方法.

    demo1

    假设你是农场主,有一小块土地,你要将这块土地均匀地分成方块,且分出的方块要尽可能大.

    def land(x, y):
        if (x == y): # 基线条件
            return x
        else: # 循环条件
            z = x - y
            if z > y:
                x = z
            else:
                x = y
                y = z
            return land(x, y)
    
    print(land(1680, 640)) # 80
    

    demo2

    给定一个数字数组,将这些数字相加,并返回结果.

    # 使用循环
    def sum(arr):
        total = 0
        for x in arr:
            total += x
    	return total
    
    print(sum([1, 2, 3, 4])) # 10
    
    # 使用递归
    def sum(arr, i, ans):
        if len(arr) > i:
            return sum(arr, i+1, ans + arr[i])
    	else:
            return ans
        
    print(sum([1, 2, 3, 4], 0, 0)) # 10
    

    2 快速排序

    基准值:pivot

    分区:partitioning

    def quicksort(array):
        if len(array) < 2:
            return array
        else:
            pivot = array[0] # 将第一个元素作为基准值
            less = [i for i in array[1:] if i <= pivot] # 小于基准值的数组
            greater = [i for i in array[1:] if i > pivot] # 大于基准值的数组
            return quicksort(less) + [pivot] + quicksort(greater)
        
    print(quicksort([10, 5, 2, 3]))
    print(quicksort([3, 5, 2, 1, 4]))
    

    3 再谈大O表示法

    3.1 比较合并排序和快速排序

    快速排序在平均情况下运行时间为O(nlogn),而合并排序的运行时间总是O(nlogn),为何不使用合并排序?

    因为它们的常量不一样,假设快速排序每一步1毫秒,合并排序的每一步需要1秒

    3.2 平均情况和最糟情况

    快速排序的性能高度依赖于选择的基准值

    最糟情况:

    一般情况:

    平均情况:

    4 小结

    • D&C将问题逐步分解,使用D&C处理列表时,基线条件很可能是空数组或只包含一个元素或数组
    • 实现快速排序时,请随机地选择用作基准值的元素,快速排序的平均运行时间为O(nlogn)
    • 大O表示法中的常量有时候很重要,这就是快速排序比合并排序快的原因
    • 在比较二分查找和简单查找时,常量无关紧要,因为列表很长时,O(logn)比O(n)快得多
  • 相关阅读:
    小学二年级四则运算软件需求规格说明书
    周活动总结
    构建之法阅读笔记01
    学习进度条01
    四则运算
    软件工程概论
    课后作业1
    继承与多态-课后作业
    python文件处理-将图像根据坐标画矩形标记
    python文件处理-将图像根据坐标切割成若干小图
  • 原文地址:https://www.cnblogs.com/okokabcd/p/9282016.html
Copyright © 2011-2022 走看看