2-路归并排序以及Java实现(学习笔记)

2-路归并排序以及Java实现(学习笔记)

1.步骤

(1)把n个有序表两两组合,组合要保证新序列有序,得到ceil(n/2)个序列。(ceil表示向上取整)

(2)2-路归并排序就是重复步骤(1),直到只有1个序列。

(3)举例说明(非常简单):
在这里插入图片描述

2.性能分析

(1)时间复杂度
最好最坏平均情况下都是O( nlog(n) )
因为序列两两组合趟数为floor( log(2,n) ),而两两组合需要时间为O(n),得到最终的O( n
log(n) )

(2)空间复杂度
每趟组合需要一个数组辅助,空间界限为O(n)

(3)稳定性
稳定的,两两组合能保证指针指向元素值相等时候,前一个序列优先。故相等元素先后顺序不改变。

3.Java代码实现

(1)Java可以比较任意两个对象大小,我之前的博客有提到(https://blog.csdn.net/weixin_42111859/article/details/104132520),这里用int举例子(扩展到任意对象相当轻松)
(2)我并没有使用递归实现
(3)涉及到了有序表拼接的知识,L1[1,2,…,m]和L2[1,2,…,m]拼接的时间复杂度为O(m+n)
(4)代码中@Test是JUnit单元测试,放在主函数中运行是一样的

代码如下:

    private static int[] b;

    // 拼接有序表,可优化的
    private static void jointOrderedList(int[] array, int st1, int ed1, int st2, int ed2) {
    
    
        //此方法调用前,要求b已经被初始化
        int st = st1;
        int bIndex = 0;
        while (true) {
    
    
            if (st1 < ed1 && st2 < ed2) {
    
    
                if (array[st1] <= array[st2]) {
    
    
                    b[bIndex++] = array[st1];
                    st1++;
                } else {
    
    
                    b[bIndex++] = array[st2];
                    st2++;
                }
                continue;
            } else if (st1 < ed1 && st2 >= ed2) {
    
    
                b[bIndex++] = array[st1];
                st1++;
                continue;
            } else if (st1 >= ed1 && st2 < ed2) {
    
    
                b[bIndex++] = array[st2];
                st2++;
                continue;
            } else {
    
    
                break;
            }
        }
        for (int i = 0; i < bIndex; i++) {
    
    
            array[st++] = b[i];
        }
    }

    public static void mergeSort(int[] array) {
    
    
        b = new int[array.length];
        int len = 1;
        for (int i = 1; i <= Math.floor(array.length / 2.0); i++) {
    
    
            for (int st = 0; st < array.length; ) {
    
    
                int ed = st + len * 2 > array.length ? array.length : st + len * 2;
                jointOrderedList(array, st, st + len, st + len, ed);
                st = ed;
            }
            len *= 2;
        }
    }

    @Test
    public void testMergeSort() {
    
    
        int[] a = {
    
    4, 7, 9, 6, 5, 2, 3};
        System.out.println(Arrays.toString(a));
        mergeSort(a);
        System.out.println(Arrays.toString(a));
    }

运行结果:

在这里插入图片描述

注解:代码中有序表拼接的判断可以用变量表示,防止重复判断,更好一点

转载请注明出处,谢谢合作

猜你喜欢

转载自blog.csdn.net/weixin_42111859/article/details/104180872