Java基础随笔-归并排序

算法思想

归并排序算法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。(采用的是分治法的策略

实现过程

①. 将序列每相邻两个数字进行归并操作,形成 floor(n/2)个序列,排序后每个序列包含两个元素;

②. 将上述序列再次归并,形成 floor(n/4)个序列,每个序列包含四个元素;

③. 重复步骤②,直到所有元素排序完毕(递归实现)

代码实现

/**
 * ClassName:MergeSrot
 * Author:LFM
 * Date:2019/6/20 16:24
 **/
public class MergeSrot {

    public static int[] sort(int [] a) {
        if (a.length <= 1) {
            return a;
        }
        //右移运算符,>>1相当于除以2
        int num = a.length >> 1;
        //该方法是将源数组按指定长度赋值到另一个新数组(从下标from开始复制)(不包括结尾元素)
        int[] left = Arrays.copyOfRange(a, 0, num);
        int[] right = Arrays.copyOfRange(a, num, a.length);

        //递归调用,让源数组分成每个数组都只有一个元素为止
        int [] lefted = sort(left);
        int [] righted = sort(right);
        //下面这个操作是要递归至源数组元素剩下一个元素才能执行,传入新数组排好序返回完成一次递归操作
        return mergeTwoArray(lefted, righted);
    }

    public static int[] mergeTwoArray(int[] a, int[] b) {
        int i = 0, j = 0, k = 0;
        int[] result = new int[a.length + b.length]; // 申请额外空间保存归并之后数据

        while (i < a.length && j < b.length) { //选取两个序列中的较小值放入新数组
            if (a[i] <= b[j]) {
                result[k++] = a[i++];
            } else {
                result[k++] = b[j++];
            }
        }

        while (i < a.length) { //序列a中多余的元素移入新数组
            result[k++] = a[i++];
        }
        while (j < b.length) {//序列b中多余的元素移入新数组
            result[k++] = b[j++];
        }
        return result;//最后返回排好序的数组
    }

    public static void main(String[] args) {
        int[] b = {3, 1, 5, 4, 6, 2, 0};
        System.out.println(Arrays.toString(sort(b)));
    }
}

运行结果

在这里插入图片描述
这个算法要理解的就是递归那一部分,分治策略就是将原问题分解为大致相等的小问题,把小问题解决再合并成

所以这个算法其中完成一次递归操作后是回到上一次递归的结尾处。意思就是递归到最深层次(就是左右长度都为1或者说左右数组都之后一个元素之后),完成排序操作后再一层一层出来(出来的过程就是把排好序的小问题合并的过程)。

时间复杂度

在这里插入图片描述
可见归并排序是一个稳定排序算法,从效率上看,归并排序可算是排序算法中的”佼佼者”. 假设数组长度为n,那么拆分数组共需logn, 又每步都是一个普通的合并子数组的过程,时间复杂度为O(n), 故其综合时间复杂度为O(nlogn)。另一方面, 归并排序多次递归过程中拆分的子数组需要保存在内存空间, 其空间复杂度为O(n)。 和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间。

猜你喜欢

转载自blog.csdn.net/weixin_42341232/article/details/93071945