基础排序算法之并归排序(Merge Sort)

并归排序是学习分治法 (Merge Sort) 的好例子。而且它相对于选择,插入,冒泡排序来说,算法性能有一定提升。我首先会描述要解决的问题,并给出一个并归排序的例子。之后是算法的思路以及给出伪代码。算法的实现部分用Python完成。最后自己尝试说明白算法分析。

 

问题描述

问题描述很简单,输入一组未排序的数组,如左边的数组,通过并归排序算法的计算,输出一组正确排序的数组,如右边的数组。

如果利用上面这个例子来做并归排序的话,应该首先将该数组切割成两半,对左边一半进行排序,在对右边一半进行排序,在合并排序好的左右数组。如下图所示:

思路和伪代码

可以从例子中看出,并归排序就是一个先分后合的过程:

  1. 递归排序左半部分数组;
  2. 递归排序右半部分数组;
  3. 合并 (Merge) 这两部分生成最后结果。 

合并 (Merge)过程的核心思想就是:给左右两个数组分别设定一个标记符号i和j,通过比对当前i和j位置的数的大小,选择小的值加入到最后的结果中去。

合并(Merge) 的伪代码:

 1 C = output[length=n]
 2 A = 1st sorted array[n/2]
 3 B = 2st sorted array[n/2]
 4 i = 1
 5 j = 1
 6 for k=1 to n
 7     if A(i) < B(j)
 8         C(k) = A(i)
 9         i++
10     else B(j) < A(i)
11         C(k) = B(j)
12         j++
13 end

 

算法实现

 

 1 def merge(left, right):
 2     result = []
 3     i, j=0, 0
 4     ll, lr = len(left), len(right)
 5     while i < ll and j < lr:
 6         if i < ll and j < lr:
 7             if left[i] < right[j]:
 8                 result.append(left[i])
 9                 i = i+1
10             else:
11                 result.append(right[j])
12                 j =j+1       
13     result+=left[i:]
14     result+=right[j:]
15     return result
16 
17 
18 def merge_sort(datalist):    
19     length=len(datalist)
20     result=datalist
21     if length>1:        
22         left=datalist[0:int(length/2)]
23         right=datalist[int(length/2):length]       
24         left=merge_sort(left)
25         right=merge_sort(right)
26         result=merge(left,right)
27     return result
View Code

 

算法分析

首先来分析在合并 (Merge) 过程的所需要的运行时间。

 1 C = output[length=n]
 2 A = 1st sorted array[n/2]
 3 B = 2st sorted array[n/2]
 4 i = 1
 5 j = 1
 6 for k=1 to n
 7     if A(i) < B(j)
 8         C(k) = A(i)
 9         i++
10     else B(j) < A(i)
11         C(k) = B(j)
12         j++
13 end

第4和5行分别需要一次操作,整个for循环中,一次循环需要四次操作,假如有m个数那么for循环整个需要4m次操作,那么最后的运行时间为4m+2。因为m总是大于1,所以为了方便计算,假设最后运行时间小于6m。

之后再来看整个算法的运行时间,采用递归树的方法,树的高度为lg­n+1,树的每一层运行时间都是6n,总共的运行时间为6nlgn+6n。所以合并排序的时间复杂度为O(nlgn)。

 

posted on 2013-08-29 11:59  热爱GIS的坏蜀黍  阅读(992)  评论(1编辑  收藏  举报