基础排序算法:归并排序

一、原理:

  本算法基于归并这个简单的操作:即将两个有序的数组合并成一个更大的有序数组。

  归并排序:要将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。

  

二、实现:

  1、java实现自顶向下归并(Comparable接口):

 

 1 public class MergeCollation
 2 {
 3     private static Comparable[] aux;  //归并所需的辅助数组
 4     
 5     private static boolean less(Comparable v, Comparable w)
 6     { 
 7         //compareTo检测v是否小于w,为真返回负,为假返回正,相等返回零
 8         return v.compareTo(w) < 0;
 9     }
10 
11     public static void merge(Comparable[] a, int lo, int mid, int hi)
12     {
13         //将a[li...mid] 和 a[mid+1..hi] 归并
14         int i = lo, j = mid +1;
15         
16         for (int k = lo; k <= hi; k++) //将a[lo..hi]复制到aux[lo..hi]
17             aux[k] = a[k];
18         
19         for (int k = lo; k <= hi; k++)
20             if (i > mid)
21                 a[k] = aux[j++];  //左半边用尽(取右半边的元素)
22             else if (j > hi)
23                 a[k] = aux[i++];  //右半边用尽(取左半边的元素)
24             else if (less(aux[j], aux[i]))
25                 a[k] = aux[j++];  //右半边的当前元素小于左半边的当前元素(取右半边的元素)
26             else
27                 a[k] = aux[i++];  //左半边的当前元素小于右半边的当前元素(取左半边的元素)
28     }
29     
30     public static void sort(Comparable[] a)
31     {
32         aux = new Comparable[a.length];  //一次性分配空间
33         sort(a, 0, a.length - 1);  // 排序
34     }
35     
36     public static void sort(Comparable[] a, int lo, int hi)
37     {
38         // 将数组a[lo..hi]排序
39         if (hi <= lo)
40             return;  //递归到只有一个元素时,放回
41         int mid = lo + (hi - lo) / 2;
42         sort(a, lo, mid);  //将左半边排序
43         sort(a, mid+1, hi);  //将右半边排序
44         merge(a, lo, mid, hi);  //归并结果
45         
46     }
47 }

 

 

 

 

merge函数举例配图:

 

归并排序举例配图:

 

 

  2、python实现:

 1 #比较函数
 2 def less(x, y):  
 3         return x < y
 4 
 5 
 6 def merge(seq, lo, mid, hi):
 7         aux = []
 8         i, j = lo, mid
 9         while i < mid and j < hi:
10                 if less(seq[i], seq[j]):
11                       aux.append(seq[i])
12                       i += 1
13                 else:
14                         aux.append(seq[j])
15                         j += 1
16         if i == mid:
17                 aux += seq[j:hi]
18         else:
19                 aux += seq[i:mid]
20         seq[lo:hi] = aux[:]
21 
22 #递归实现
23 def mergesort(seq, lo, hi):
24         if lo < hi - 1:
25                 mid = (lo + hi) // 2
26                 mergesort(seq, lo, mid)
27                 mergesort(seq, mid, hi)
28                 merge(seq, lo, mid, hi)
29 
30 #包装函数
31 def sort(seq):
32         mergesort(seq, 0, len(seq))

 

三、特点:

  1、对于长度为N的任意数组,自顶向下的归并排序需要1/2NlogN至NlogN次比较

  2、对于对于长度为N的任意数组,自顶向下的归并排序最多需要访问数组6NlogN次

  3、由1与2可知,归并排序所需时间和NlogN成正比

 

posted @ 2015-10-28 16:30  slient_guest  阅读(170)  评论(0编辑  收藏  举报