• 归并排序


    概念介绍

      有同学想了解归并排序,今天它来了!归并排序的基本思想是“分治”,也是就把一个大问题递归分成许多个小问题依次求解。咱们直接上例子。

    图片来源(https://www.cnblogs.com/chengxiao/p/6194356.html

      咱们对{ 8, 4, 5, 7, 1, 3, 6, 2 }进行排序,对于分的过程,咱们只是把一个待排序的整体数组,分成了一个个小的单元,此时数组的顺序并未发生任何改变。分完了之后,就是治,治的过程是将各个小单元合并成有序序列,如下图,8与4,5与7,1与3,6和2都进行了排序,形成一个个有序序列。

      

       那么小单元是如何合并的?咱们举个例子:对[4,8]和[5,7]进行排序。我们要知道,A=[4,8]和B=[5,7]本身就是有序序列,由上图可以看到合并的结果,但是看不到合并的过程。两个数组是这样比的:先取A[0] = 4,B[0] = 5进行比较,4<5,将4从A中移除,放入到一个新的数组C中,此时A=[8],B=[5,7],C=[4]。然后重复上述操作,取A[0] = 8,B[0] = 5进行比较,8>5,将5从B中移除,放入C中,此时此时A=[8],B=[7],C=[4,5],最后就是8和7比较了。总结就是:每次取两个有序数组的头结点进行比较,小的结点放入新的数组中。

    代码实现

      // 分+治的过程
        public static void mergeSort(int[] arr, int left, int right, int[] temp) {
            if (left < right) {
                // 通过mid将代分的数组分成两部分
                int mid = (left + right) / 2;
                // 从左向mid递归
                mergeSort(arr, left, mid, temp);
                // 从mid向右递归
                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];
                    i++;
                    t++;
                } else {
                    temp[t] = arr[j];
                    j++;
                    t++;
                }
            }
            // (二)把剩余数据的一边数据依次全部填充到temp中
            while (i <= mid) {
                temp[t] = arr[i];
                i++;
                t++;
            }
            while (j <= right) {
                temp[t] = arr[j];
                j++;
                t++;
            }
            // (三)将temp数组的元素拷贝到arr
            t = 0;
            int tempLeft = left;
            while (tempLeft <= right) {
                arr[tempLeft] = temp[t];
                t++;
                tempLeft++;
            }
        }

      至此,代码编写完成,Git地址:https://github.com/HollowCup/algorithms-and-data-structure,具体实现位于algorithm工程下的sort目录MergeSort,如果发现不足之处,请联系我进行更改,十分感谢!关注我,带你了解更多排序算法!

  • 相关阅读:
    理解TCP/IP,SOCKET,HTTP,FTP,RMI,RPC,webservic
    flyway 管理数据库版本
    【代码工具】Lombok来优雅的编码
    windows常用
    Elasticsearch-基础介绍及索引原理分析
    Zipkin和微服务链路跟踪
    【安装】Mac rabbitMQ
    数论四大定理的证明与部分应用(含算术基本定理)
    洛谷 P1306 斐波那契公约数 题解
    「SWTR-04」Sweet Round 04 游记
  • 原文地址:https://www.cnblogs.com/maguanyue/p/13546307.html
Copyright © 2020-2023  润新知