归并排序算法:
归并排序算法是一种经典的分治算法。
分治
分治算法分为由三部分组成:
分解:将原问题分解为一系列子问题;
解决:递归的解决各个子问题。若子问题足够小,那么直接求解。
合并:将子问题的结果合并成原问题。
归并排序步骤
归并排序完全依照了上述模式,直观的操作如下:
分解:将n个元素分成各含n/2个元素的子序列;
解决:用合并排序法对两个子序列递归地排序;
合并:合并两个已经排序的子序列,已得到排序结果。
这里递归的边界是序列长度为1时,显然是有序的。
合并过程
这里最关键的步骤,是合并步骤里如何合并两个有序的序列,并保证合并后的序列依然有序。
假设有序的序列为递增的,A、B为需要合并的序列,C为合并后的结果序列,p、q分别为A和B的下标,top为C的下标。定义如果一个下标大于序列的长度后,表示的值为无穷大。
初始状态:p、q、top均为0.
操作:选择A[p]和B[q]中的小的元素,加入到C[top]中,然后让较小的元素所在的序列的下标加一,top加一。当A[p]和B[q]均为无穷大时,结束操作。
由于每次操作均是比较A[p]和B[q],然后取较小者加入C中,显然时间复杂度是O(n)的。
归并排序时间复杂度分析:
假设归并排序一个长度为n的序列需要的时间为T(n)。
首先归并排序分如下三个步骤:
分解:这一步是把序列分为两个子序列,只需要常量时间,O(1);
解决:递归的解决规模为n/2的两个子问题,时间为2*T(n/2);
合并:上面已经证明,只需时间O(n)。
那么接下来可以UI递归的表示出所需的时间T(n):
当n = 1是,T(n) = O(1);
否则:T(n) = 2*T(n/2) + O(n)。
可以证明出上述的T(n)其实就是O(n*log(n))。
T(n) = 2*T(n/2) + O(n)
= 2*(2*T(n/4) + O(n/2) + O(n)
= 4*T(n/4) + 2*O(n/2) + O(n)
= 4*T(n/4) + 2*O(n)
= 8*T(n/8) + 8*O(n/8) + 2*O(n)
= 8*T(n/8) + 3*O(n)
= x*T(1) + y*O(n)
显然y即为n除多少次才为1,y = log2(n),x等于2^y,那么T(n) = O(n*log(n))。
一个容易理解的代码:
Python is very beautiful!
def merge_sort(array):
if len(array) > 1:
mid = len(array) / 2
left = merge_sort(array[:mid])
right = merge_sort(array[mid:])
return m