排序算法之归并排序

定义

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and
Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子
序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

实现思路

递归方法。
终止条件:元素只有一个时,本身有序。end - start == 0;
像二叉树一样进行递归。
递归完成后,需要做两步,1:将当前要归并的左右区间元素放入创建的辅助数组中。2:进行归并(放入array原数组中)。

代码实现

/**
 * @Author: huang
 * @Date: 2021/9/8 15:28
 * @Description: 归并排序
 */
public class Main9 {
    public static void main(String[] args) {
        int[] array = {5,16,4,3,20,17};
        mergeSort(array);
        for (int i : array) {
            System.out.print(i + " ");
        }
    }


    //归并外壳,我们新创建与array长度一样的数组,每次在新创建的数组中进行归并再放入array中
    private static void mergeSort(int[] array) {
        int[] tmp = new int[array.length];
        mergeSortInternal(array, 0, array.length - 1, tmp);
    }

    /**
     *
     * @param array 待排序的数组
     * @param start 待排序数组的起点
     * @param end 待排序数组的起点
     * @param tmp 零时辅助数组
     */
    private static void mergeSortInternal(int[] array, int start, int end, int[] tmp) {
        if (end - start == 0) {
        //元素只有一个时,本身有序。
            return;
        }
        //数组长度大于1,进行递归和归并
        int middle = (start + end) / 2;
        //进行middle左右区间递归
        mergeSortInternal(array, start, middle, tmp);
        mergeSortInternal(array, middle + 1, end, tmp);

        //把当前要排序的左右区间放到辅助数组tmp中
        for (int i = start; i <= middle; i++) {
            tmp[i] = array[i];
        }
        for (int i = middle+1; i <= end; i++) {
            tmp[i] = array[i];
        }

        //进行归并,用left来指向左区间第一个元素,right指向右区间第一个元素,flg代表array第一个元素下标
        int left = start;
        int right = middle + 1;
        int flg = start;

        while(left <= middle && right <= end) {
            //进行比较,放入到array中
            if (tmp[left] <= tmp[right]) {
                array[flg++] = tmp[left++];
            }else {
                array[flg++] = tmp[right++];
            }
        }

        //还需注意左右区间长度不一,比较不完,长的区间剩余的部分肯定比已经归并的元素大,直接放入array剩余空间中
        if (left <= middle) {
            while(left <= middle) {
                array[flg++] = tmp[left++];
            }
        }
        if (right <= end) {
            while(right <= end) {
                array[flg++] = tmp[right++];
            }
        }
    }
}
时间复杂度空间复杂度
O(n * log(n))O(n)
数据不敏感数据不敏感

稳定性:稳定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值