当前位置: 首页 > article >正文

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

文章目录

  • 归并排序
        • 1.递归实现
        • 2.非递归实现


归并排序


  • 时间复杂度: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];//对齐下标
        }
    }
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];//对齐下标
        }
    }

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

偷cyk的图


http://www.kler.cn/news/135537.html

相关文章:

  • 设计模式-组合模式-笔记
  • 应试教育导致学生迷信标准答案惯性导致思维僵化-移动机器人
  • Android描边外框stroke边线、rotate旋转、circle圆形图的简洁通用方案,基于Glide与ShapeableImageView,Kotlin
  • 【双指针】快乐数
  • Wireshark TS | 应用传输缓慢问题
  • 【运维篇】Redis 性能测试工具实践
  • 米家竞品分析
  • OceanBase 4.2.1 LTS 发版 | 一体化数据库首个长期支持版本
  • 数据结构与算法之美学习笔记:22 | 哈希算法(下):哈希算法在分布式系统中有哪些应用?
  • 面向开发者的Android
  • CXL崛起:2024启航,2025年开启新时代
  • 前端食堂技术周刊第 105 期:TS 5.3 RC、Vite 5.0、W3C 新任 CEO、有害的 Pinia 模式、2024 更快的 Web
  • Kotlin学习之函数
  • 【HarmonyOS开发】配置开发工具DevEco Studio
  • 基于SSM的高校毕业选题管理系统设计与实现
  • kubernetes部署jenkins
  • flink源码分析之功能组件(一)-metrics
  • openGauss学习笔记-128 openGauss 数据库管理-设置透明数据加密(TDE)
  • Hibernate 函数 ,子查询 和原生SQL查询
  • YOLOV8部署Android Studio安卓平台NCNN
  • Java Web——JS中的BOM
  • CISP模拟试题(三)
  • 前置语音群呼与语音机器人群呼哪个更好
  • python-opencv 培训课程笔记(1)
  • React整理总结(四)
  • LeetCode 面试题 16.25. LRU 缓存
  • js 对象数组删除某一个特定的对象
  • 达索系统3DEXPERIENCE云端设计新体验
  • CSS-表格属性(1)
  • docker数据卷详细讲解及数据卷常用命令