算法学习笔记(8)-归并排序

排序算法——归并排序 目录: 🍉算法思想 🥝算法描述 🍒实例 具体步骤: 代码实现: 🍍算法效率分析。 归并排序(Mergesort)是建立在归并的有效操作上进行排序,主要采用分治法将已有序的子序列合并,得到完全有序的序列。即先让每一小段有序,再让小段之间变得有序。将两个有序段归并为一个有序段,称为二路归并;有序段称为归并段。分治法将一个大问题成一些小的问题然后递归求解,而的阶段则将分的阶段得到的各答案“修补”在一起,即分而治之。如下图所示。...... 阅读详情

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

一、分治法思想

在这里插入图片描述

二、归并排序的效率

  1. 时间复杂度O(nlogn)
  2. 空间复杂度O(n)

二、Java代码实现

1.数组形式

第一种归并排序被称为自顶向下的归并排序,这也是最经典的版本,它基于分治法,即将大数组拆分为左右两个小数组【小数组再次拆分为左右两个小数组直到不可拆分】,然后调用归并方法将已经拆分好并且有序的小数组归并成大数组即完成了归并排序。

    public void sort(int[] array) {
        int[] aux = new int[array.length];
        int left = 0;
        int right = array.length - 1;
        mergeSort(array, aux, left, right);
    }

    private void mergeSort(int[] array, int[] aux, int left, int right) {
        // 递归终止条件
        if (left >= right) {
            return;
        }
        // 划分左右数组:分
        int mid = left + ((right - left)>>1);
        mergeSort(array, aux, left, mid);
        mergeSort(array, aux, mid + 1, right);
        // 合并当前的两个左右数组:治
        merge(array, aux, left, mid, right);
    }

    private void merge(int[] array, int[] aux, int left, int mid, int right) {
    	// 左链表最右边索引
        int i = mid;
        // 右链表最右边索引
        int j = right;
        // 辅助链表最右边索引
        int cur = right;
        while (i >= left && j > mid) {
            if (array[i] >= array[j]) {
                aux[cur--] = array[i--];
            } else {
                aux[cur--] = array[j--];
            }
        }
        // 将剩余的数据复制到辅助数组中
        while (i >= left) {
            aux[cur--] = array[i--];
        }
        while (j > mid) {
            aux[cur--] = array[j--];
        }
        // 将辅助数组中已排序部分复制到原数组
        for (int k = left; k <= right; k++) {
            array[k] = aux[k];
        }
    }
2.链表形式
 public ListNode sort(ListNode head) {
        //递归终止条件
        if (head == null || head.next == null){
            return head;
        }
        // 使用快慢指针将链表拆分成左右两个链表
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode rightStart = slow.next;
        slow.next = null;
        //分割链表成两个部分:分
        ListNode l1 = sort(head);
        ListNode l2 = sort(rightStart);
        //合并两个链表:治
        ListNode res = merge(l1, l2);
        return res;
    }

    private ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                cur.next = l1;
                l1 = l1.next;
            } else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        if (l1 != null) {
            cur.next = l1;
        }
        if (l2 != null) {
            cur.next = l2;
        }
        return dummy.next;
    }

三、改进

归并排序和快锁排序一样依赖于递归和分治,这在大数组的情况下性能优异,归并排序的时间复杂度为0(nlogn),但是当数组比较小的时候,归并排序由于大量的递归调用以及需要创建空间复杂度为0(n)的辅助空间,性能或许比插入排序或者选择排序低。所以这时可以有两种选择:

1.数据量小

当数据量小到一定范围时可以选择插入排序:

public static void sort(int[] a, int[] aux, int left, int right) {
		//数据范围,视情况而定
        int N = 100;
        if (right - left <= N) {
            //改用插入排序
            InsertSort(a);
            return;
        } 
        //中间划分点
        int middle = left + (right - left)/2;
        //将左半边排序
        sort(a, aux, left, middle);
        //将右半边排序
         sort(a, aux, middle + 1, right);
        //归并
        merge(a, aux, left, middle, right);
    }
2. 左右数组已经完全排好序

检测待归并的两个子数组是否已经有序,如果已经有序则直接复制进aux中。

C语言试题176之实现归并排序算法 题目:实现归并排序算法概念及其介绍 归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。适用说明 当有 n 个记录时,需进行 logn 轮归并排序,每一轮归并,其比较次数不超过 n,元素移动次数都是 n,因此,归并排序的时间复杂度为 O(nlogn)。归并排序时需要和待排序记 阅读详情

相关推荐

MoveIt控制睿尔曼RM65机械臂:从仿真到实机的3种控制模式对比

本文详细解析了使用MoveIt框架控制睿尔曼RM65机械臂的三种核心模式:拖动规划、目标姿态规划和Python API控制,从Gazebo仿真到实机部署的完整实现路径。通过ROS环境配置、控制参数优化及实机过渡技术,为工业自动化和机器人研究提供实用指南。

729

归并排序及其优化

Q:什么是归并排序? A:它是建立在归并操作上的一种有效的排序算法;是采用分治法的一个非常典型的应用;是一种稳定的基本思想要将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。优点?它能保证将任意长度为 N 的数组排序所需时间和 NlogN 成正比;缺点?所需的额外空间和 N 成正比。原地归并的抽象方法Q:为什么需要原地归并? A:因为用归并将一个大数组排序时,需要进行多次

TinyDolphin的博客 3569

TEM图像处理实战指南:从基础操作到金属材料分析

本文提供了一份全面的透射电镜(TEM)图像处理实战指南,涵盖从基础操作到金属材料深度分析的全流程。重点讲解了TEM图像预处理、选区电子衍射(SAED)标定、高分辨像(HRTEM)分析及STEM图像应用等核心技能,并结合金属材料(如铝合金、钢)的析出相鉴定、位错分析和界面结构研究等实际案例,帮助研究者从原始数据中准确提取晶体结构、缺陷及成分信息。

weixin_29284201的博客 211

C++组合数计算全解析:公式法、递推法与质因数分解法的选型与实战

组合数是算法设计与概率统计中的基础工具,其计算看似简单,但在C++实现中常面临溢出与精度问题。直接套用阶乘公式时,n=21即超出long long范围;而浮点替代方案在大数下又会丢失有效数字。本文从组合数的数学定义出发,分析中间过程数据膨胀的本质,引出三种工程实现路径:公式法通过对称优化与边乘边除控制中间结果,适用于小规模单次计算;递推法借助帕斯卡恒等式构造杨辉三角,适合批量查询与动态规划场景;质因数分解法则将乘除运算转化为指数加减,支持高精度输出,能处理数万规模。掌握这些方法的边界与选型原则,可有效提升算

weixin_34198453的博客 458

ArcGIS AddIn开发之:属性刷兼属性修改工具

1、arcmap中选中一个要素,点击读取要素,把属性读取到datagridview中。4、重新在arcmap中选择其他要素,可以单选多选,选中之后,点击“粘贴”按钮,先遍历要素,再遍历字典,把所有字段值,存到要素中。3、点击“复制”按钮,把需要复制的字段的 ID 和 字段内容,存到字典中。一般在arcmap修改要素属性的流程是:开启编辑,选择图层,找到要素,修改,保存,关闭编辑。但是用这个插件,只需要:选择要素,读取属性,修改内容,回车。添加了一个属性修改功能。人无我有,人有我优,做插件,就是要卷起来。

坐听风雨 2165

无人自行车平衡控制:最小二乘法动态零点拟合实践

本文探讨了无人自行车平衡控制中动态零点的重要性及实现方法。通过最小二乘法拟合车头角度与ROL值的线性关系,解决了固定零点在转向时导致的稳定性问题。实践表明,动态零点拟合能显著提升系统平衡稳定性并降低能耗。

uran的专栏 661

归并排序算法优化

1. 什么是归并排序? 更详细的解释可以百度,这里说说其主要思想: 归并排序是采用分治思想,将所有的数均匀的分成n个等分的组,然后依次取(x, x+1) 2个等分组,将他们合并排序,形成一个新的组,然后递归即可,最后会合并为一个组,这个组就是有序的。 示范一下: 要排序的11个数 : [8, 3, 4, 2, 22, 17, 13, 66, 9, 2, 100] 第1步:分成11个等分:...

weixin_30642267的博客 214

注册电气工程师详细教材

注册电气工程师详细教材

qq_40844444的博客 4261

归并排序(分治思想 自顶向下)

原理: 归并排序是分治法的一个典型的应用。先使每个子序列有序,再将两个有序子序列合并成一个有序表。 如图所示就是归并排序的基本步骤。首先利用函数递归,将原数组不断分割直至变成不可分割的,只含一个元素的子序列,此时每个子序列都能被看成是有序的子序列。然后进行合并,每一轮合并将逆着拆分的过程逐渐在原数组中形成有序。 复杂度: 平均、最好、最坏的时间复杂度都为:O(n*log n)。在数据量...

左云帆 1004

Ardupilot EKF3核心算法《开篇》

Ardupilot EKF3核心算法本专栏重点,透彻,详细的分析了ardupilot的EKF3,保证是你看到的最完美的EKF3资料,相信你的选择不会错误。网上EKF资料真是太多,说真的没有一篇讲解好的。!!

陌城烟雨 1416

海康Visionmaster-全局脚本:VM 加载方案后自动执行 的方法,如何让VM在方案加载后自动执行流程?

海康Visionmaster-全局脚本:VM 加载方案后自动执行 的方法,如何让VM在方案加载后自动执行流程?

视觉人机器视觉的博客 2039

改进归并排序算法

一、针对经典归并排序算法问题的改进措施 (1)针对递归层次问题 采用能在小规模集合上有效工作的其它算法,直接对小规模集合处理。 如INSERTIONSORT算法 (2)针对元素频繁移动问题 采用一个称为链接信息数组LINK(1:n)的数据结构,记录归并过程中A中的元素相对于其排序后在分类表中位置坐标的链接关系。 LINK(i)取值于[1,n],是指向A的元素的指针:在分类表中它指向下一个元素在A中的位置坐标。 二、具体实现 m_improved.h #pragma once //直接插入排序 void i

snoopy19981210的博客 3157

新能源汽车电池及充电原理详解

本文详细介绍了新能源汽车的电池包结构、铅酸电池充放电原理,以及交流和直流充电的工作原理和优缺点。内容涵盖电池串联并联原因、充电设备如车载充电机、交流充电桩和直流充电桩的介绍,以及不同充电模式的连接方式。通过对充电过程的深入探讨,有助于读者理解新能源汽车的充电技术。

让你爱上电路设计 4528

【算法】归并排序概念及例题运用

本篇博文对归并排序概念及例题运用做了一个较为详细的介绍,不知道对你有没有帮助呢觉得博主写得还不错的三连支持下吧!会继续努力的~

2301_77954967的博客 3753

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

用java实现归并排序算法

用java实现归并排序 一. 归并排序的思路 归并排序通过不断的将原数组进行拆分(通常拆分成左右两项),一直到剩下一项,然后分别将拆分的子数组进行合并,此时,两个子数组已经是排好序的,所以合并排序只需要进行一趟排序即可完成,所以此类排序需要两个步骤:1.拆分原数组 2.合并子数组。因此此算法是经典的分治算法。 拆分算法的思路 利用递归,不断得寻找左子数组和右子数组,一直到数组的长度为一 合并算法的...

Mark的博客 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

常见排序算法之归并排序——归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法 (Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序 列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。...

保护小周ღ的博客 2403

归并排序算法

归并排序(Merge Sort)是一种基于分治策略的高效排序算法。它的基本思想是将一个数组分成两个子数组,分别对这两个子数组进行排序,然后将排好序的子数组合并成一个最终的排序数组。

2401_86810295的博客 2228

算法第四版学习笔记之归并算法

软件:DrJava 参考书:算法(第四版) 章节:2.2归并排序(以下截图是算法配套视频所讲内容截图) 1:mergesort 归并排序 2:bottom-up mergesort 自底向上的归并排序 3:sorting complexity 排序的复杂度 4:comparators 比较器 5:stability 稳定性 、   1:mergesort 归并排序   1 /********...

weixin_34220179的博客 175

经典排序算法(8)——归并排序算法详解

1

渴望,就奋力追寻... 2267

分治算法(8)_归并排序_翻转对

分治算法完结篇_分治算法(8)_归并排序_翻转对,感兴趣的宝子们千万不要错过!!! 下一个算法专栏_链表 感兴趣的宝子们记得点赞关注不迷路哦!!!

wer24_25的博客 986

算法-8-归并排序

目录 1、描述 2、特点 3、自顶向下的归并排序 4、自底向上的归并排序 5、归并排序的优化 6、使用场景 7、归并排序是一种渐进最优的基于比较排序的算法。 1、描述 归并排序是基于递归方式进行排序的。它其实可以分为两步: 第一步 递归,(递归就是将数组递归拆分成很小的数组) 第二步,合并。(合并就是将这些很小的数组比较合并成有序的数组) 它的核心思想是一个长度为N的数组...

Yo.o 527

归并排序(Merge Sort)图解,归并排序算法

归并排序是建立在归并操作上的一种有效、稳定的排序算法,该算法采用非常经典的分治法(分治法可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化),归并排序的思路很简单,速度呢,也仅此于快速排序,接下来我们详细的看看归并排序的过程。基本思路: 第一步:将序列中待排序数字分为若干组,每个数字分为一组。 第二步:将若干组两两合并,保证合并的组都是有序的。 第三步:重复第二步的操作,直到剩下最后一组即为有序数列。详细步骤: 首先将数组

学到牛牛官网帐号 9061

算法之归并排序算法

介绍归并排序之前,先将一实现归并排序所运用的运用的方法----分治法。 许多有用的算法在数据结构上市递归的:为了解决一个给定的问题,算法一次或多次用其自身来解决紧密相关的若干子问题。这些算法典型地遵循分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解。 分治模式在每层递归中都有三个步骤: 分解原问题为若干个子问题,这

Phenixfate的专栏 1424
上一篇: JVM学习(1)-虚拟机内存区域划分以及内存溢出
下一篇: Linux(5)-购买、配置以及使用阿里云服务器
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值