• 排序——归并排序


    一、基本介绍

    ​ 归并排序是采用分治的策略实现排序的一种方法,即将问题分为若干个小问题,递归的去求解,然后将各个小问题合在一起,便完成整个排序过程。

    二、排序过程

    对数组arr = [9 , 4 , 5 , 3 , 7 , 1 , 6 , 2 ] 从小到大排序:

    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  左边有序序列的初始索引
     * @param mid   中间索引
     * @param right 右边索引
     * @param temp  做中转的数组
     */
    public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
    
        int i = left; // 初始化i, 左边有序序列的初始索引
        int j = mid + 1; //初始化j, 右边有序序列的初始索引
        int t = 0; // 指向temp数组的当前索引
    
        //先把左右两边(有序)的数据按照规则填充到temp数组,直到左右两边的有序序列,有一边处理完毕为止
        while (i <= mid && j <= right) {
            //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素,填充左边大数据到临时数组
            if (arr[i] <= arr[j]) {
                temp[t] = arr[i];
                t += 1;
                i += 1;
            } else { //反之,将右边有序序列的当前元素,填充到temp数组
                temp[t] = arr[j];
                t += 1;
                j += 1;
            }
        }
    
        //把有剩余数据的一边的数据依次全部填充到temp
        while (i <= mid) { //左边的有序序列还有剩余的元素,就全部填充到temp
            temp[t] = arr[i];
            t += 1;
            i += 1;
        }
        while (j <= right) { //右边的有序序列还有剩余的元素,就全部填充到temp
            temp[t] = arr[j];
            t += 1;
            j += 1;
        }
        //将temp数组的元素拷贝到arr
        t = 0;
        int tempLeft = left; //
        while (tempLeft <= right) {
            arr[tempLeft] = temp[t];
            t += 1;
            tempLeft += 1;
        }
    }
    
  • 相关阅读:
    RDA安装
    关闭SELinux
    Linux下开启关闭防火墙
    长事务管理
    增加复制表
    Python使用property函数定义的属性名与其他实例变量重名会怎么样?
    Python使用property函数定义属性访问方法如果不定义fget会怎么样?
    Python使用property函数和使用@property装饰器定义属性访问方法的异同点分析
    第8.18节 Python类中内置析构方法__del__
    Python中的列表解析和列表推导是一回事吗?
  • 原文地址:https://www.cnblogs.com/Mhang/p/12333172.html
Copyright © 2020-2023  润新知