归并排序详细解说

思路分析

归并排序:是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使
子序列段间有序。

图解

在这里插入图片描述

代码示例

1)递归方法

//有两个重要的特点,可以适用于外部排序(数据在磁盘上),也可以适用于链表排序
    // (希尔,堆排序,快速排序依赖随机访问能力,都不适合链表排序)
    //基本思路来源于基本问题:把两个有序链表/数组合并成一个

    //[low,mid) 有序区间
    //[mid,high) 有序区间
    //两个区间进行合并
    public static void  merge(int[] array,int low, int mid, int high){
        int[] output = new int[high - low];
        int outputIndex = 0;//记录当前output数组中被放入了多少元素
        int cur1 = low;//第一个区间的起始下标
        int cur2 = mid;//第二个区间的起始下标

        while (cur1 < mid && cur2 < high){
            //以下条件写成小于等于,才能保证稳定性
            if (array[cur1] <= array[cur2]){
                output[outputIndex] = array[cur1];
                outputIndex++;
                cur1++;
            }else {
                output[outputIndex] = array[cur2];
                outputIndex++;
                cur2++;
            }
        }
        //当以上循环结束的时候,肯定有一个cur到达末尾,另一个还剩下一些内容
        //把剩余的内容老被到output中
        while (cur1 < mid){
            output[outputIndex] = array[cur1];
            outputIndex++;
            cur1++;
        }
        while (cur2 < high){
            output[outputIndex] = array[cur2];
            outputIndex++;
            cur2++;
        }

        //把output的元素搬运到原来的数组
        for (int i = 0; i < high - low; i++){
            array[low + i] = output[i];
        }

    }

    public static void mergeSort(int[] array){
        mergeSortHelper(array,0,array.length);
    }

    //[low,high)前闭后开区间
    private static void mergeSortHelper(int[] array, int low, int high) {
        if (high - low <= 1){
            return;
        }
        int mid = (low + high) / 2;
        mergeSortHelper(array,low,mid);
        mergeSortHelper(array,mid,high);

        //当我们把左右区间归并排序完了,说明左右区间已经是有序区间了
        merge(array,low,mid,high);
    }

2)非递归方法

public static void mergrSortByLoop(int[] array){
        //引入一个gap变量进行分组
        //当gap为1的时候,0 1是一组  2 3是一组  4 5是一组。。。
        //当gap为2的时候,就是[0,1]和【2,3】是一组。。。。
        //当gap为4的时候,【0,1,2,3】和【4,5,6,7】是一组
        for (int gap = 1; gap < array.length; gap *= 2){
            //接下来进行具体的分组合并
            for (int i = 0; i < array.length; i+= 2*gap){
                int beg = i;
                int mid = i + gap;
                int end = i + 2*gap;
                //防止下标越界
                if (mid > array.length){
                    mid = array.length;
                }
                if (end > array.length){
                    end = array.length;
                }
                merge(array,beg,mid,end);
            }
        }
    }

性能分析

时间复杂度:
O(n * log(n))

空间复杂度:
O(n)

稳定性:
稳定排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值