算法——分治和快速排序
Posted 代码综合征
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法——分治和快速排序相关的知识,希望对你有一定的参考价值。
分治也是一种递归式问题解决方法。快速排序是使用分治法的一种排序算法。
分治
分治一般有两个步骤:找出基线条件,不断将问题分解,直到符合基线条件。
例子:比如计算数组[2,4,6]中所有元素的和,可以使用循环,也可以使用分治递归。
接受一个列表,如果列表为空,就返回0.
否则,计算列表中除第一个数字外的其他数字的综合,将其与第一个数字相加,再返回结果。
设计数组的递归函数,基线条件通常是数组为空或只包含一个元素。
快速排序
快速排序的原理:
首先从数组中选择一个元素,这个元素被称为基准值。
接下来找出比基准值小的元素以及比基准值大的元素,这被称为分区。
得到了一个由所有小于基准值的数字组成的子数组,一个由所有大于基准值的数字组成的子数组,以及基准值。
再对子数组进行同样的分组排序的操作,最后组合起来就是有序的数组。
下面是快速排序的代码:
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(n)表示运行时间是c*n,c是算法所需的固定时间量。
比如对于简单查找和二分查找来说,简单查找的运行时间是 10ms*n
,而二分查找的运行时间是 1s*log n
。
虽然看起来是简单查找的时间常量小,单数如果n非常大的情况下,二分查找的速度几乎没有变化,比简单查找快得多。
每个算法的复杂度都有个平均情况和最糟情况。比如针对快速排序,基准值的选择对复杂度的影响就很大。
如果基准值选择一直选择第一个的话,调用栈非常长,但是如果每次都选择中间那个的话,调用栈可以很短。
在最糟情况下,栈长为O(n),而在最佳情况下,栈长为O(log n)。而每一层所需时间为O(n)。
在最佳情况下,整个算法需要的时间为O(n) * O(log n) = O(n log n)。在最糟情况下,该算法的运行时间为O(n) * O(n) = O(n2)。
小结
分治将问题逐步分解。使用分治处理列表时,基线条件很可能是空数组或只包含一个元 素的数组。
实现快速排序时,请随机地选择用作基准值的元素。快速排序的平均运行时间为O(n log n)。
大O表示法中的常量有时候事关重大,这就是快速排序比合并排序快的原因所在。
比较简单查找和二分查找时,常量几乎无关紧要,因为列表很长时,O(log n)的速度比O(n) 快得多。
以上是关于算法——分治和快速排序的主要内容,如果未能解决你的问题,请参考以下文章