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];
        }

    }

你可能感兴趣的:(Java关于排序的介绍2-归并排序)