归并排序

归并排序

归并排序基本思想:

将原数组从中间分开,分成两个子数组,然后继续将子数组从中间分开,直到把所有子数组分解到只有

一个元素,此时分的过程就结束了

然后开始治,递归回退一层,将两个子数组合并成一个新的有序的数组,然后依次回退与其它子数组合并成

新的数组,直到合并成原始数组

归并排序基本思想示意图1:

归并排序基本思想示意图2:

代码实现

public static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if (left < right) {
            int mid = (left + right) / 2;//中间索引,从此处将数组划分成两份
            //向左递归进行分解
            mergeSort(arr, left, mid, temp);
            //向右递归进行分解
            mergeSort(arr, mid + 1, right, temp);
            //当分解到只有两个元素的数组时,就开始排序合并
            merge(arr,left,mid,right,temp);
        }
        //只有一个元素了,就不能合并,则回退一层,再合并
    }


	/**
	 *@param arr   排序的原始数组
     * @param left  A有序数组的起始索引
     * @param mid   中间索引,也就是A数组的最后一个索引
     * @param right B数组的终止索引
     * @param temp  合并的数组
     */
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left;//左边有序序列的初始索引
        int j = mid + 1;//右边有序序列的初始索引
        int t = 0;//t指向temp数组的当前索引

        //(一)
        //先把左右两边(有序)的数据按规则填充到temp数组
        //直到左右两边有一边遍历结束
        while (i <= mid && j <= right) {
            //比较两数组中当前索引的数,哪个小就加入到temp
            if (arr[i] <= arr[j]) {
                temp[t++] = arr[i++];
            } else {
                temp[t++] = arr[j++];
            }
        }

        //(二)
        //将没有遍历完的数组的剩余元素依次全部填充到temp数组
        //因为如果当前数组还有剩余,就说明另外一个数组已经遍历完成了
        while (j <= right) {
            temp[t++] = arr[j++];
        }

        while (i <= mid) {
            temp[t++] = arr[i++];
        }


        t = 0;
        //(三)
        //将temp数组的元素拷贝到arr
        //第一次合并是 left=0,right=1  left=2,right=3
        //第二次合并是 left=0,right=3
        //最后合并是 left=0,right=7
        for (int k = left; k <= right; k++) {
            arr[k] = temp[t++];
        }
    }
posted @ 2021-03-12 23:22  编程の小白  阅读(67)  评论(0编辑  收藏  举报