分而治之(divide and conquer,D&C)
WIKI
In computer science, divide and conquer is an algorithm design paradigm based on multi-branched recursion. A divide and conquer algorithm works by recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem.
工作原理
Step1:找出基线条件,这种条件必须尽可能简单
Step2:不断将问题分解,直到符合基线条件
示例:函数sum
快速排序(Quicksort)
快速排序使用了D&C
WIKI
Quicksort (sometimes called partition-exchange sort) is an efficient sorting algorithm, serving as a systematic method for placing the elements of an array in order.
Python代码
# coding:utf-8
"""
Code ideas:
将列表首元素设为基准值,寻找其位置
low游标走过的位置都比基准值小,否则暂停不走,继续走high游标
high游标走过的位置都比基准值大,否则暂停不走,交换两游标数值
两游标交汇位置为基准值位置
"""
def quick_sort(alist, first, last):
if first >= last:
return
n = len(alist)
high = last
low = first
num_mid = alist[first]
while low < high:
while low < high and alist[high] >= num_mid:
high -= 1
alist[low] = alist[high]
while low < high and alist[low] < num_mid:
low += 1
alist[high] = alist[low]
alist[low] = num_mid
quick_sort(alist, first, low - 1)
quick_sort(alist, low + 1, last)
if __name__ == "__main__":
alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
quick_sort(alist, 0, len(alist) - 1)
print alist
"""
Code ideas:
选择基准值
将数组分成两个子数组:小于基准值的元素和大于基准值的元素
对两个子数组进行快速排序
"""
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([54, 26, 93, 17, 77, 31, 44, 55, 20])
>>>
[17, 20, 26, 31, 44, 54, 55, 77, 93]
再谈大O表示法
快速排序(quicksort)VS合并排序(merge sort)
快速排序平均O(nlogn),c1*nlogn
合并排序总是O(nlogn),c2*nlogn
实际上快速排序比合并排序快得多,因为快速排序的常量比合并排序小
快速排序的性能依赖于选择的基准值