归并排序(Merge sort)
定义 归并排序采用分治策略进行比较操作排序,将待排序的n个元素分解为个含n/2个元素的两部分,使用递归或其它方式迭代地两个子序列进行同样的排序操作,然后合并两个已排序的子序列。 分析 序列的划分 序列的划分较为简单直接,n为奇数时两部分长度相差1,可以规定将较长的一部分作为第二部分的长度。 序列的合并 从最基本的合并开始,如果划分到一个子序列仅有一个元素时,不能进一步划分,对该子序列的归并排序会直接返回,对应于n=1时的归并排序,是直接求解的不需要进行归并操作。当单元素子序列归并排序完成时,将两个子序列进行合并得到两个元素的子序列,对应于n=2时的归并排序就完成了,以此类推,不失一般性考虑如何合并任意大小的两个已排序子序列的问题。 对于序列的划分操作需要进行lgn次,每次都需要对n个元素进行合并操作,而合并本身也是对两个有序子序列的再排序,合并的开销必须尽可能地小,至少需要将所有子序列遍历一遍,其渐进复杂度下界是Ω(n)。如果采用原址排序的方式,由于两个子序列除了自身是有序的,两者之间没有任何联系,这会是一个一般性的排序问题。因此,为了利用已排序的子序列,将两者复制后依次进行比较并合并回原序列中。 实现 def merge_sort(A, start, end): if end - start <= 1: return mid = (end + start) / 2 merge_sort(A, start, mid) merge_sort(A, mid, end) merge(A, start, mid, end) def merge(A, start, mid, end): left = [] right = [] for i in xrange(start, mid): left.append(A[i]) for i in xrange(mid, end): right.append(A[i]) i = 0 j = 0 current = start left_size = len(left) while i < left_size and j < len(right): if left[i] <= right[j]: A[current] = left[i] i += 1 else: A[current] = right[j] j += 1 current += 1 for k in xrange(i, left_size): A[current] = left[k] current += 1 if __name__ == '__main__': A = [12, 12, 123, 234, 1, 2, 3, 4000, 12, 234, 1, 891] merge_sort(A, 0, len(A)) print A