本文是在阅读《算法图解》时的一些记录。作者Aditya Bhargava,袁国忠译。
3.2、每个递归函数都有两部分:基线条件(base case)和递归条件(recursive case)
1 def countdown(i): 2 print i 3 # base case 4 if i <= 0: 5 return 6 # recursive case 7 else: 8 countdown(i-1) 9 10 countdown(5)
4.1、D&C(divide and conquer)工作原理
- 找出简单的基线条件
- 确定如何缩小问题的规模,使其符合基线条件
如欧几里得算法:
1 def gcd(a, b): 2 while a != 0: 3 a, b = b % a, a 4 return b 5 6 print gcd(512, 3200)
def sum(list): if list == []: return 0 return list[0] + sum(list[1:])
4.2快速排序
1 def quicksort(array): 2 if len(array) < 2: 3 # base case, arrays with 0 or 1 element are already "sorted" 4 return array 5 else: 6 # recursive case 7 pivot = array[0] 8 # sub-array of all the elements less than the pivot 9 less = [i for i in array[1:] if i <= pivot] 10 print 'less' , less; 11 # sub-array of all the elements greater than the pivot 12 greater = [i for i in array[1:] if i > pivot] 13 print "greater" , greater 14 return quicksort(less) + [pivot] + quicksort(greater) 15 16 print quicksort([10, 5, 2, 3, 128, 99, 11])
快速排序的最糟情况下为O(n2),最佳情况时间为O(nlogn),只要每次都随机选择基准值,快速排序的平均运行时间就将是(nlogn)(看运气吧!)。
快速排序是最快的排序算法之一,D&C典范。
4.4、小结
- 使用D&C处理列表时,基线条件很可能是空数组或只包含一个元素的数组;
- 实现快速排序时,随机的选择作为基准值的元素,平均运行时间为O(nlogn)
- 大O表示法中,常量同样很重要,归并排序同样为O(nlogn),但其常数就快速排序大,故其性能低于快速排序;
- 比较简单查找和二分查找,当数据量很大时,O(logn)比O(n)大很多,故常量无关紧要。