快速排序

D&C递归算法-快速排序

①解决问题的过程包括两个步骤:
找出基线条件
不断将问题分解,直到符合基线条件
②使用循环求数字列表的和

def sum(list):
    total=0
    for x in list:
        total+=x
    return total
print(sum([2,4,6,8]))

使用递归求数字列表的和

def sum(list):
    if list==[]:
        return 0
    return list[0]+sum(list[1:])
print(sum([1,2,3,4]))

③使用循环求列表中元素的个数

def count(arr):
    index=0
    for x in arr:
        index=index+1
    return index
print(count([1,2,3,4]))

使用递归求列表中元素的个数

def count(list):
    if list==[]:
        return 0
    return 1+count(list[1:])
print(count([1,2,3,4]))

④用循环找出列表中最大的数字

def max(arr):
    maxnum=arr[0]
    for i in range(1,len(arr)):
        if arr[i]>maxnum:
            maxnum=arr[i]
    return maxnum
print(max([1,2,3,4]))

用递归求列表中最大数字


def max(list):

    if len(list) == 2:

        return list[0] if list[0] > list[1] else list[1]

    sub_max = max(list[1:])

    return list[0] if list[0] > sub_max else sub_max
print(max([1,2,3,4]))

⑤二分查找的基线条件是数组只包含一个元素,如果要查找的值跟这个元素相同,就找到了,否则,说明不在数组中。
在二分查找的递归条件中,把数组分成两半,其中一半丢掉,对另一半进行二分查找。

快速排序

①最简单的数组的基线条件为数组为空或只包含一个元素,只需原样返回数组,不用排序。

def quicksort(dist)
	if len(dist)<2return list

②更长的数组,暂时将第一个元素用作基准值,接下来找比基准值小的元素以及比基准值大的元素。

分区

①一个由所有小于基准值的数字组成的子数组
②基准值
③一个由所有大于基准值的数组组成的子数组

如何对子数组进行排序

①对于只包含两个元素的数组(左边的子数组)以及空数组(右边的子数组),进行快速排序

quicksort([15,10])+[33]+quicksort([])#=>[10,15,33]

不管哪个元素作为基准值,这都管用。
②对包含多个元素的数组进行快速排序
1、选择基准值
2、将数组分成两个子数组,小于基准值的元素和大于基准值的元素
3、对这两个子数组进行快速排序

快速排序代码

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]))

再谈大O表示法

①快速排序的运行时间O(n log n)

比较合并排序和快速排序

假设有下面打印列表中每个元素的简单函数

def print_items(list):
    for item in list:
        print(item)

这个函数遍历列表中每个元素并打印出来,迭代整个列表一次,运行时间为O(n)。现在修改,使打印每个元素前休眠1s.

list=[2,4,6,8,10]
##print_items(list)
from time import sleep
def print_items2(list):
    for item in list:
        sleep(1)
        print(item)
    
print_items2(list)

运行时间也为O(n)
①有的时候,常量的影响可能很大,对快速查找和合并查找就是如此。快速查找的常量比合并查找小,因此运行时间都为O(n log n),快速查找更快。

平均情况和最糟情况的时间

①最佳情况也就是平均情况O(n)*O(logn) 后者为层数,也即调用栈的高单独,前者为每层需要时间,整个时间为O(n log n)
②最糟情况 O(n2)

小结

①使用D&C处理列表,基线条件很可能是空数组或只包含一个元素的数组。
②实现快速排序时,请随机得选择用作基准值的元素。
③大O表示法中常量有时候事关重大,这就是快速排序比合并排序块的原因所在。
④比较简单查找和二分查找时,常量几乎无关紧要,因为列表很长,O(log n)的速度比O(n)快的多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值