递归实现的归并排序是算法设计中分治思想的典型应用。实现归并排序的另一种方法是先归并那些微型数组,然后再成对的归并得到的子数组,循环操作,最终得到排序完成的数组。这种实现方法比标准递归方法代码量更少。
算法实现:
public class MergeBU {
private static int [] aux;
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=k+1)
aux[k]=a[k];
for (int k=lo;k<=hi;k=k+1)
if (i>mid) a[k]=aux[j++];
else if (j>hi) a[k]=aux[i++];
else if (aux[j]<aux[i]) a[k]=aux[j++];
else a[k]=aux[i++];
list_deal.printArray(a);
}
public static void sort(int[] a)
{
int N=a.length;
aux=new int[N];
for (int sz=1;sz<N;sz=sz+sz)
for (int lo=0;lo<N-sz;lo=lo+sz+sz)
merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1,N-1));
}
public static void main(String[] args) {
int[] a={534,745,264,864,136,967,254,745,734,269,538,265,825,158,139,100};
list_deal.printArray(a);
sort(a);
list_deal.printArray(a);
}
}
排序过程:
534 745 264 864 136 967 254 745 734 269 538 265 825 158 139 100
534 745 264 864 136 967 254 745 734 269 538 265 825 158 139 100
534 745 264 864 136 967 254 745 734 269 538 265 825 158 139 100
534 745 264 864 136 967 254 745 734 269 538 265 825 158 139 100
534 745 264 864 136 967 254 745 734 269 538 265 825 158 139 100
534 745 264 864 136 967 254 745 269 734 538 265 825 158 139 100
534 745 264 864 136 967 254 745 269 734 265 538 825 158 139 100
534 745 264 864 136 967 254 745 269 734 265 538 158 825 139 100
534 745 264 864 136 967 254 745 269 734 265 538 158 825 100 139
264 534 745 864 136 967 254 745 269 734 265 538 158 825 100 139
264 534 745 864 136 254 745 967 269 734 265 538 158 825 100 139
264 534 745 864 136 254 745 967 265 269 538 734 158 825 100 139
264 534 745 864 136 254 745 967 265 269 538 734 100 139 158 825
136 254 264 534 745 745 864 967 265 269 538 734 100 139 158 825
136 254 264 534 745 745 864 967 100 139 158 265 269 538 734 825
100 136 139 158 254 264 265 269 534 538 734 745 745 825 864 967
100 136 139 158 254 264 265 269 534 538 734 745 745 825 864 967
自底向上的归并排序会多次遍历整个数组,根据数组的大小进行两两归并。
当数组长度为2的幂时,自顶向下和自底向上的归并排序所用的比较次数和数组访问次数相同,只是顺序不同。
自底向上的归并排序比较适合用链表组织的数据。