归并排序

来源:互联网 发布:一落叶而知天下秋启示 编辑:程序博客网 时间:2024/06/05 05:13
public static void merge(int[] a,int lo,int mid,int hi){int i = lo ,j = mid + 1;             for(int k=lo;k<=hi;k++){aux[k] = a[k];}for(int k=lo;k<=hi;k++){if(i > mid) {a[k] = aux[j++]; //左边越界,放右边元素}else if(j > hi){a[k] = aux[i++]; //右边越界,放左边元素}else if(less(aux[i],aux[j])){ a[k] = aux[i++]; //主要比较操作,放入较小元素}else{ a[k] = aux[j++]; //同上}}}

既然是归并排序,当然要把两个有序的小数组归并为一个有序的大数组。其中:i和j为两个数组的起点;再利用辅助数组aux,在数组a上排序。


下面有两种归并排序的实现:自顶向下 ;  自底向上

1 自顶向下:

public static void mergeSort(int[] a){aux = new int[a.length];mergeSort(a,0,a.length-1); //自顶向下  }public static void mergeSort(int[] a,int lo,int hi){if(hi <=lo) {return;}int mid = lo + (hi-lo) / 2;mergeSort(a,lo,mid);      //排序左半边数组mergeSort(a,mid+1,hi);  //排序右半边数组merge(a,lo,mid,hi);  //调用归并}

在mergeSort函数中,先申请了一个固定长度的aux数组(这个函数只执行了一次).再调用带lo和hi参数的mergeSort函数。

思想:利用嵌套先将大数组拆至长度为一的小数组,再归并为有序的大数组。


2 自底向上:

public static void mergeSort(int[] a){aux = new int[a.length];for(int sz=1;sz<a.length;sz = sz+sz){for(int lo=0;lo<a.length-sz;lo+=sz+sz){                      //自底向上merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1, a.length-1));}}}

在mergeSort函数中,利用循环将直接从长度为1的小数组开始进行归并。下一次循环小数组长度为2,4,8,16....。


归并排序复杂度:

在此排序算法中用到了辅助空间保存临时数组。所以空间复杂度不是最优;其最坏的时间复杂度~NlgN。


原创粉丝点击