• 归并排序详解:递归实现+非递归实现(图文详解+代码)



    归并排序


    • 时间复杂度:O ( N * logzN ) 每一层都是N,有log2N层
    • 空间复杂度:O(N),每个区间都会申请内存,最后申请的数组大小和array大小相同
    • 稳定性:稳定

    目前为止,稳定的排序有:插入、冒泡、归并

    • 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,采用了分治法

    在这里插入图片描述

    • 将待排序列分解,先使每个子序列有序,再使子序列段间有序
    • 将已有序的子序列合并,得到完全有序的序列
    • 若将两个有序表合并成一个有序表,称为二路归并
    1.递归实现

    在这里插入图片描述

    
        /**
         * 归并排序
         * @param array
         */
        public static void mergeSort(int[] array) {
            mergeSortFunc(array,0,array.length-1);
        }
    
        private static void mergeSortFunc(int[] array, int left, int right) {
            //结束条件
            if (left >= right) {
                return;
            }
            //进行分解
            int mid = (left + right) / 2;
            mergeSortFunc(array, left, mid);
            mergeSortFunc(array, mid + 1, right);
            //左右分解完成后,进行合并
            merge(array, left, right, mid);
    
    
        }
    
        //进行合并
        private static void merge(int[] array, int start, int end, int mid) {
            int s1 = start;
            int s2 = mid + 1;
            int[] tmp = new int[end - start + 1];
            int k = 0;//k为tmp数组的下标
            while (s1 <= mid && s2 <= end) {//两个数组中都有数据
                //进行比较,放到新申请的数组
                if (array[s1] <= array[s2]) {
                    tmp[k++] = array[s1++];
                } else {
                    tmp[k++] = array[s2++];
                }
            }
            //因为有&&条件,数组不一定走完
            while (s1 <= mid) {
                tmp[k++] = array[s1++];
            }
            while (s2 <= end) {
                tmp[k++] = array[s2++];
            }
            //此时,将排好的tmp数组的数组,拷贝到array
            for (int i = 0; i < tmp.length; i++) {
                array[i+start] = tmp[i];//对齐下标
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    2.非递归实现

    在这里插入图片描述

    
    
        /***
         * 归并排序,非递归实现
         * @param array
         */
        public static void mergeSort2(int[] array) {
            int gap = 1;
            while (gap < array.length) {
                //i += gap * 2 i每次跳到下一组
                for (int i = 0; i < array.length; i += gap * 2) {
                    int left = i;
                    //要避免mid和right越界
                    int mid = left + gap - 1;
                    if(mid>=array.length){
                        mid = array.length-1;//修正越界的情况
                    }
                    int right = mid + gap;
                    if (right>=array.length){//修正越界的情况
                        right = array.length-1;
                    }
                    merge(array,left,right,mid);//进行合并
                }
                gap *=2;//2倍数扩大组数
            }
        }
        //进行合并
        private static void merge(int[] array, int start, int end, int mid) {
            int s1 = start;
            int s2 = mid + 1;
            int[] tmp = new int[end - start + 1];
            int k = 0;//k为tmp数组的下标
            while (s1 <= mid && s2 <= end) {//两个数组中都有数据
                //进行比较,放到新申请的数组
                if (array[s1] <= array[s2]) {
                    tmp[k++] = array[s1++];
                } else {
                    tmp[k++] = array[s2++];
                }
            }
            //因为有&&条件,数组不一定走完
            while (s1 <= mid) {
                tmp[k++] = array[s1++];
            }
            while (s2 <= end) {
                tmp[k++] = array[s2++];
            }
            //此时,将排好的tmp数组的数组,拷贝到array
            for (int i = 0; i < tmp.length; i++) {
                array[i + start] = tmp[i];//对齐下标
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    点击移步博客主页,欢迎光临~

    偷cyk的图

  • 相关阅读:
    简单使用_matlab生成数据帧
    【Redis】RedisTemplate序列化传输数据
    MySQL优化(1):B+树与索引
    武汉市技术转移示范机构绩效考核对象、内容和申报流程、材料
    Window11右键菜单没有新建菜单解决
    添加Java服务
    有什么好的开源自动化测试框架可以推荐?
    隐式转换这个概念你听说过没?
    fabric.js点击group 种的子元素
    RabbitMQ 如何保证消息不丢失
  • 原文地址:https://blog.csdn.net/m0_64003319/article/details/134519447