基础排序算法:归并排序
一、原理:
本算法基于归并这个简单的操作:即将两个有序的数组合并成一个更大的有序数组。
归并排序:要将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。
二、实现:
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成正比