Java关于排序的介绍2-归并排序

本篇博客主要是介绍归并排序

归并排序的核心是归并俩个已经有序的数组
首先我们先针对俩个有序的数组进行合并排序

/**
    * arr1 第一个有序的数组
    * size1 数组一的大小
    * arr2 第二个有序的数组
    * size2 数组二的大小
    * arr3 保存数组一和数组二合并以后并排序的数组
    */
    public static void sort(int arr1[], int size1, int arr2[], int size2, int arr3[]) {
        int index1 = 0, index2 = 0, index3 = 0; // 分别记录三个数组的索引
        while (index1 < size1 && index2 < size2) { // 如果俩个有序数组的索引都在合理范围
            // 比较赋值 
            if (arr1[index1] < arr2[index2]) {
                arr3[index3++] = arr1[index1++];
            } else {
                arr3[index3++] = arr2[index2++];
            }
        }
        while (index1 < size1) { // 数组2已经遍历排序完成,数组1还有数据没有遍历排序
            arr3[index3++] = arr1[index1++];
        }
        while (index2 < size2) {
            arr3[index3++] = arr2[index2++];
        }
    }

下面我们介绍如何对对一个数组进行排序
根据上面的例子,可以知道首要要把一个数组拆分成俩个数组,然后对每一半的数组进行排序,形成有序数组。然后在通过归并排序实现数组有序。
那么问题来了如何将一个数组拆分成俩个数组并分别排序呢?
递归来了
不断的对数组进行折半拆分并进行归并排序。
拆分

/**
    * 对数组进行拆分
    * 注意该地方的拆分并不是真的将数组拆分了 
    * source 数据源
    * arr    最后保存有序数据的数组
    * start  拆分数组的起始位置
    * end    拆分数组的结束位置
    */
    public static void split(int source[], int arr[], int start, int end) {
        if (start == end) { // 递归结束条件
            return;
        }
        // 获取数组拆分的位置
        int mid = (start + end) / 2;

        // 通过递归分割前面数据
        split(source, arr, start, mid);

        // 通过递归分割后面数据
        split(source, arr, mid + 1, end);

        // 排序
        sort(source, arr, start, mid + 1, end);

    }

排序

    /**
     * 排序 (将leftPtr到rightBound的数据进行排序)
     * 
     * @param source
     *            数据源
     * @param arr
     *            最后保存有序数据的数组
     * @param leftPtr
     *            左起始位置
     * @param rightPtr
     *            右起止位置
     * @param rightBound
     *            右边界
     */
    public static void sort(int source[], int arr[], int leftPtr, int rightPtr, int rightBound) {

        int index = 0; // arr 下标索引
        int mid = rightPtr - 1; // 分割位置 分为左右俩部分模拟俩个数组
        int leftBound = leftPtr; // 计算左边界
        int n = rightBound - leftBound + 1; // 数据个数

        // 保证新数组中数据有序
        while (leftPtr <= mid && rightPtr <= rightBound) {
            if (source[leftPtr] < source[rightPtr]) {
                arr[index++] = source[leftPtr++];
            } else {
                arr[index++] = source[rightPtr++];
            }
        }

        while (leftPtr <= mid) { // 右边的已经遍历比较结束 直接通过左边数据赋值
            arr[index++] = source[leftPtr++];
        }

        while (rightPtr <= rightBound) { // 左边的已经遍历比较结束 直接通过右边数据赋值
            arr[index++] = source[rightPtr++];
        }

        // 更新数据源数据顺序 保证本次合并数据的在原始数组有序
        for (int i = 0; i < n; i++) {
            source[leftBound + i] = arr[i];
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值