1、分而治之(divide and conquer, D&C)
工作原理:找出简单的基线条件;确定如何缩小问题的规模,使其符合基线条件。
2、递归求和
def addarr(arr):
if arr==[]:
return 0
else:
return arr[0]+addarr(arr[1:])
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)
4、大O表示法的理解
大O表示时间复杂度时常常不考虑常亮,因为不同数量级的增长下,常量的作用微乎其微,如简单查找(O(n))和二分查找(O(logn))。但是考虑同种数量级的增长时必须考虑常量的影响。如快速排序与合并排序。
5、快速排序的两种极端情况
最糟糕的情况:每次基准值都选取第一个元素,总共有O(n)层,每一层的所需时间为O(n),算法运行时间为O(n)*O(n)=O(n^2)
最糟糕的情况:每次基准值都选取中间的元素,总共有O(logn)层,每一层的所需时间为O(n),算法运行时间为O(logn)*O(n)=O(nlogn)
6、小结
- D&C将问题逐步分解。 使用D&C处理列表时, 基线条件很可能是空数组或只包含一个元素的数组。
- 实现快速排序时, 请随机地选择用作基准值的元素。 快速排序的平均运行时间为O (n log n )。
- 大O表示法中的常量有时候事关重大, 这就是快速排序比合并排序快的原因所在。
- 比较简单查找和二分查找时, 常量几乎无关紧要, 因为列表很长时, O (log n )的速度比O (n )快得多。