首页 > 代码库 > 自底向上归并排序(Merge Sort)

自底向上归并排序(Merge Sort)

一、思路

另一种实现归并排序的方法是,先归并微型数组再成对归并得到的子数组,直到将整个数组归并在一起。

我们先进行1-by-1归并,然后2-by-2归并,4-by-4归并,如此下去。

在最后一次归并中,第二个数组可能比第一个数组要小。

 

二、代码实现

关键代码:

    public static void sort(Comparable[] input) {
        
        int N = input.length;
        aux = new Comparable[N];
        
        for(int sz = 1; sz < N; sz += sz) {
            for(int lo = 0; lo < N - sz; lo += sz + sz) {
                merge(input, lo, lo+sz-1, Math.min(N-1, lo+sz+sz-1));
            }
        }
            
    }

 

测试数据:M E R G E S O R T E X A M P L E

 

输出结果1:

M E R G E S O R T E X A M P L E 
merge(input,    0,    0,    1)E M R G E S O R T E X A M P L E 
merge(input,    2,    2,    3)E M G R E S O R T E X A M P L E 
merge(input,    4,    4,    5)E M G R E S O R T E X A M P L E 
merge(input,    6,    6,    7)E M G R E S O R T E X A M P L E 
merge(input,    8,    8,    9)E M G R E S O R E T X A M P L E 
merge(input,   10,   10,   11)E M G R E S O R E T A X M P L E 
merge(input,   12,   12,   13)E M G R E S O R E T A X M P L E 
merge(input,   14,   14,   15)E M G R E S O R E T A X M P E L 
merge(input,    0,    1,    3)E G M R E S O R E T A X M P E L 
merge(input,    4,    5,    7)E G M R E O R S E T A X M P E L 
merge(input,    8,    9,   11)E G M R E O R S A E T X M P E L 
merge(input,   12,   13,   15)E G M R E O R S A E T X E L M P 
merge(input,    0,    3,    7)E E G M O R R S A E T X E L M P 
merge(input,    8,   11,   15)E E G M O R R S A E E L M P T X 
merge(input,    0,    7,   15)A E E E E G L M M O P R R S T X 
A E E E E G L M M O P R R S T X 

对比自顶向下:

M E R G E S O R T E X A M P L E 
merge(input,    0,    0,    1)E M R G E S O R T E X A M P L E 
merge(input,    2,    2,    3)E M G R E S O R T E X A M P L E 
merge(input,    0,    1,    3)E G M R E S O R T E X A M P L E 
merge(input,    4,    4,    5)E G M R E S O R T E X A M P L E 
merge(input,    6,    6,    7)E G M R E S O R T E X A M P L E 
merge(input,    4,    5,    7)E G M R E O R S T E X A M P L E 
merge(input,    0,    3,    7)E E G M O R R S T E X A M P L E 
merge(input,    8,    8,    9)E E G M O R R S E T X A M P L E 
merge(input,   10,   10,   11)E E G M O R R S E T A X M P L E 
merge(input,    8,    9,   11)E E G M O R R S A E T X M P L E 
merge(input,   12,   12,   13)E E G M O R R S A E T X M P L E 
merge(input,   14,   14,   15)E E G M O R R S A E T X M P E L 
merge(input,   12,   13,   15)E E G M O R R S A E T X E L M P 
merge(input,    8,   11,   15)E E G M O R R S A E E L M P T X 
merge(input,    0,    7,   15)A E E E E G L M M O P R R S T X 
A E E E E G L M M O P R R S T X

 

输出结果2:

M E R G E S O R T E X A M
merge(input, 0, 0, 1)E M R G E S O R T E X A M
merge(input, 2, 2, 3)E M G R E S O R T E X A M
merge(input, 4, 4, 5)E M G R E S O R T E X A M
merge(input, 6, 6, 7)E M G R E S O R T E X A M
merge(input, 8, 8, 9)E M G R E S O R E T X A M
merge(input, 10, 10, 11)E M G R E S O R E T A X M
merge(input, 0, 1, 3)E G M R E S O R E T A X M
merge(input, 4, 5, 7)E G M R E O R S E T A X M
merge(input, 8, 9, 11)E G M R E O R S A E T X M
merge(input, 0, 3, 7)E E G M O R R S A E T X M
merge(input, 8, 11, 12)E E G M O R R S A E M T X
merge(input, 0, 7, 12)A E E E G M M O R R S T X
A E E E G M M O R R S T X

对比自顶向下:

M E R G E S O R T E X A M
merge(input, 0, 0, 1)E M R G E S O R T E X A M
merge(input, 2, 2, 3)E M G R E S O R T E X A M
merge(input, 0, 1, 3)E G M R E S O R T E X A M
merge(input, 4, 4, 5)E G M R E S O R T E X A M
merge(input, 4, 5, 6)E G M R E O S R T E X A M
merge(input, 0, 3, 6)E E G M O R S R T E X A M
merge(input, 7, 7, 8)E E G M O R S R T E X A M
merge(input, 7, 8, 9)E E G M O R S E R T X A M
merge(input, 10, 10, 11)E E G M O R S E R T A X M
merge(input, 10, 11, 12)E E G M O R S E R T A M X
merge(input, 7, 9, 12)E E G M O R S A E M R T X
merge(input, 0, 6, 12)A E E E G M M O R R S T X
A E E E G M M O R R S T X

 

当数组长度为2的幂时,自顶向下和自底向上所用的比较次数和数组访问次数正好相同,只是顺序不同。

否则,两种方法所用的比较次数和数组访问次数有所不同。

 

三、性能分析

结论:对于长度为N的任意数组,自底向上归并排序需要1/2NlgN至NlgN次比较,最多访问数组6NlgN次。

分析:见P279

 

四、排序复杂度

没有任何基于比较的算法能够保证使用少于lgN! ~ NlgN次比较将长度为N的数组排序。

 

自底向上归并排序(Merge Sort)