经典排序算法(五) —— Merge Sort 归并排序

合并法排序 合并法排序(Merge Sort)是一种基于分治思想的排序算法,其原理如下:1.将待排序数组分成两个子数组,每个子数组包含大约相等数量的元素。2.递归地对子数组进行排序,直到每个子数组的大小为1。3.将已排序的子数组合并成一个新的排序数组,合并过程中按照从小到大的顺序逐个比较两个子数组中的元素,并将较小的元素放入新数组中,直到所有元素都被放入新数组中。4.最终得到一个有序数组。合并排序的时间复杂度是O(nlogn),其中n是待排序数组的长度。它的空间复杂度是O(n)。 阅读详情

简介

约翰·冯·诺伊曼在 1945 年提出了归并排序。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

归并排序的时间复杂度是O(nlogn)。代价是需要额外的内存空间。

排序过程

实现
版本一
@Test
public void test() {
    int[] nums = new int[]{4, 2, 8, 9, 6, 3, 5, 7, 1, 2};
    int[] mergeSort = mergeSortSimple(nums, 0, nums.length - 1);
    printArray(mergeSort);
}


/*
 * 归并排序
 * @param nums 待排序数组
 * @param start 开始位置
 * @param end   结束位置
 * @return
 */
public int[] mergeSortSimple(int[] nums, int start, int end) {
    if (start == end) {
        return new int[]{nums[start]};
    }
    int mid = (start + end) / 2;
    int[] m1 = mergeSortSimple(nums, start, mid);
    int[] m2 = mergeSortSimple(nums, mid + 1, end);
    return mergeNumsSimple(m1, m2);
}

/**
  * 合并两个有序数组
  * @param num1 待合并数组1
  * @param num2 待合并数组2
  * @return 合并数组
*/
public int[] mergeNumsSimple(int[] num1, int[] num2) {
    int l1 = num1.length;
    int l2 = num2.length;
    int[] resNum = new int[l1 + l2];
    int resIdx = 0;
    int index1 = 0;
    int index2 = 0;
    while (resIdx < resNum.length) {
        while (index1 < l1 && index2 < l2) {
            resNum[resIdx++] = num1[index1] < num2[index2] ? num1[index1++] : num2[index2++];
        }
        while (index1 < l1) {
            resNum[resIdx++] = num1[index1++];
        }
        while (index2 < l2) {
            resNum[resIdx++] = num2[index2++];
        }
    }
    return resNum;
}

	
/**
 * 打印数组
 * @param nums
*/
public void printArray(int[] nums) {
    for (int num : nums) {
        System.out.print(num + "\t");
    }
    System.out.println();
}
版本二

 
@Test
public void test() {
    int[] nums = new int[]{4, 2, 8, 9, 6, 3, 5, 7, 1, 2};
    int[] res = new int[nums.length];
    mergeSortSimpleOpt(nums, 0, nums.length - 1, res);
    printArray(res);
}


/**
 * 归并排序
*/
public void mergeSortSimpleOpt(int[] nums, int start, int end, int[] res) {
        if (start == end) {
            return;
        }
        int mid = (start + end) / 2;
        mergeSortSimpleOpt(nums, start, mid, res);
        mergeSortSimpleOpt(nums, mid + 1, end, res);
        mergeOpt(nums, start, end, res);
}

/**
* 版本一递归过程中会有额外的临时数组开销,在此版本优化,直接传入定义好的结果数组做合并
*/
public void mergeOpt(int[] nums, int start, int end, int[] res) {
    int end1 = (start + end) / 2;
    int start2 = end1 + 1;

    int idx1 = start;
    int idx2 = start2;
    int resIdx = idx1 + idx2 - start2;
    while (idx1 <= end1 && idx2 <= end) {
        res[resIdx++] = nums[idx1] < nums[idx2] ? nums[idx1++] : nums[idx2++];
    }
    while (idx1 <= end1) {
        res[resIdx++] = nums[idx1++];
    }
    while (idx2 <= end) {
        res[resIdx++] = nums[idx2++];
    }
    while (start <= end) {
        nums[start] = res[start++];
    }
}
复杂度
O(nlogn)
排序算法—sort(),stable_sort(),merge() 排序目录:一.sort()二.stable_sort()三.merge()1.merge函数的作用:2.为什么引入归并排序merge()函数3.代码4.例题P1309 瑞士轮 一.sort() cppreference中的详细解释 二.stable_sort() stable_sort()遇见大小相同的值不会改变他们的位置 cppreference中的详细解释 三.merge() cpprefer... 阅读详情

相关推荐

使用C#详解常用排序算法(三):归并排序(Merge Sort)

结合C#代码讲解归并排序。

qqiang00的博客 2628

JavaScript 数据结构与算法十大经典排序算法-归并排序(五)

原理 归并排序,是先把数组从中间分成两部分,然后对前后两部分分别排序,再将排序好的连部分合并在一起。 核心思想是将两个有序的数列合并成一个大的有序序列。通过递归,层层合并,即为归并 ...

DreamFive 247

C/C++ Merge Sort排序算法详解及源码

Merge Sort(归并排序)是一种经典的分治排序算法,它将一个待排序的数组分成两个子数组,分别对子数组进行排序,然后再将排好序的子数组进行合并,从而得到最终的有序数组。

希望我的博客,能帮上你解决学习中工作中所遇到的问题 7897

排序算法-归并排序详细讲解(MergeSort)

归并,指合并,合在一起。归并排序(Merge Sort)是建立在归并操作上的一种排序算法。其主要思想是分而治之。若将两个有序集合并成一个有序表,称为2-路归并,与之对应的还有多路归并。借助一个辅助空数组,把左右两边的数组按照大小比较,按顺序放入辅助数组中即可。以下面两个有序数组为例: public static void mergeSort(int[] arr){ if (arr == null || arr.length<2){ return;

信竞星球_少儿编程题库 1万+

JSAPI微信支付(小程序)V3版本JAVA代码实战源码

1.1、商户通过JSAPI/小程序下单接口获取到发起支付的必要参数prepay_id后,再通过微信小程序调起微信支付收银台JSAPI/小程序下单_JSAPI支付|微信支付商户文档中心1.3、微信H5发起类似,结合文档,细微调整,前端返回类似,参考文档修改为微信内置浏览器调起支付即可。

java web 707

【UE5】虚幻引擎Gameplay框架

游戏实例(UGameInstance)会在引擎启动时实例化,并保持活跃直至引擎关闭。这是一种管理器类,在游戏中不存在实体,但会追踪数据和运行代码。在联网多人游戏中,游戏实例不会被复制,而是独立存在于服务器以及所有互联的客户端上。所有你希望在关卡加载间保持的内容都应存于游戏实例中。例如,游戏实例是管理游戏保存系统的到地方。游戏实例还可以充当任意数量的 游戏实例子系统 的管理器,这些子系统由游戏实例创建和销毁,并且与游戏实例本身具有相同的生命周期。在线子系统就属于这类子系统。

一个写程序的 1795

数据结构----排序算法(5):归并排序

概述 和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"...

潇雷的博客 362

FREERTOS+LWIP+IAP实现TCP、HTTP、网页访问并固件升级、更新配置 (三)lwip实现httpd服务并在web访问

在前两篇文章中配置freeRTOS和,并实现了TCP、UDP的通信协议,现在终于轮到重头戏lwip的httpd服务,LWIP官方例程中是有很多自带的网页的,但是远远不够满足实际项目的使用需求,因此我也是踩了很多坑,从前端网页制作,到网络通信的实现,到后端数据处理,从头开始学起,也是学习到了很多没接触过的东西,本章将搭建LWIP的HTTP服务使得浏览器可以访问WEB。

wangjiaheng0716的博客 2965

C语言实现归并排序

#include "sort_.h" void print_array(int *arr, int n) // 打印数组 { if(n==0){ printf("ERROR: Array length is ZERO\n"); return; } printf("%d", arr[0]); for (int i=1; i<n; i++) { printf(" %d", arr[i]); } printf(

helpluozhao123的博客 443

Quartus II 13.0安装避坑指南:从下载到破解的完整流程(附常见错误解决方案)

本文提供Quartus II 13.0软件的详细安装与破解指南,涵盖从下载准备、路径设置、主程序安装到授权配置的全流程。重点解析了破解过程中生成和修改license.dat文件的核心步骤,并针对“无法找到有效的License文件”等常见错误提供了实用的解决方案,帮助用户快速构建稳定的FPGA开发环境。

weixin_29291863的博客 760

银河麒麟V10系统grub崩溃急救指南:从光盘救援到完整恢复(附常见错误排查)

本文详细介绍了银河麒麟V10系统grub崩溃的急救方法,从使用安装光盘进入救援环境到完整恢复系统的全流程。针对不同损坏程度(轻度、中度、严重)提供了分级恢复策略,包括grub2-install和grub2-mkconfig等关键命令的使用,并附有常见错误排查表,帮助用户快速解决引导问题。

weixin_30955617的博客 483

详解十大经典排序算法(五):归并排序(Merge Sort)

在归并排序的合并阶段,将左右两个有序数组合并为一个有序数组时,可以通过判断左边数组的最大值和右边数组的最小值来优化合并操作,避免不必要的比较。这个优化点可以通过添加一个条件来判断是否需要合并,如果左边数组的最大值小于等于右边数组的最小值,则无需合并,因为两个数组已经是有序的,不需要进行额外的比较和移动。归并排序的核心思想是将一个大的数组分割成多个小的子数组,然后分别对这些子数组进行排序,最后将排序后的子数组合并起来,得到一个有序的大数组。:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

WriteBug001的博客 934

【零基础入门哈希签名架构,从Lamport到SPHINCS+】第二集 哈希签名树 Merkle Tree Authentication

在第一集中,我们一直忽略了一个问题。设想一下,假如有一个Hacker(黑客),在截获到Sender发送给Receiver的公钥之后,把这个公钥改成Hacker自己的公钥,然后再发给Receiver,那么Receiver就会误认为这是Sender的公钥。所以我们之前所说放方案,其安全性都需要建立在一个前提下:Receiver需要确认公钥确实是Sender发出的。

m0_50572808的博客 2453

排序——归并排序(Merge sort)

1945年,约翰·冯·诺依曼(John von Neumann)发明了归并排序,这是典型的分治算法的应用。 定义 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。 算法思路 归并排序算法有两个基本的操作,...

努力中的老周的专栏 18万+

【INMP441】 MEMS麦克风,让硬件“听得见”,更要“听得清”

INMP441是一款数字MEMS麦克风,采用PDM接口输出高质量数字音频信号。相比传统模拟麦克风,它具有高度集成、抗干扰强、功耗低等优势,支持通过时钟启停实现软件控制开关。该麦克风体积小巧但功能强大,内置MEMS传感器、ADC转换器等模块,适合智能音箱、语音遥控等应用。工程师可通过ESP32等主控芯片轻松连接INMP441,利用多麦克风阵列实现波束成形等高级功能。INMP441展现了数字音频采集的先进技术,为创客和智能硬件开发者提供了优秀的音频解决方案。

深耕CV 1536

不加行也能填满:用 ABAP BDC 驯服 Table Control 滚动录制缺陷,批量维护供应商银行账户

摘要 本文探讨了在SAP ECC/S4HANA系统中处理供应商主数据时,Table Control控件带来的批量导入挑战。文章指出,银行账户维护界面中Table Control的滚动动作难以被录制工具捕捉,导致批量导入数据时仅能填充前5行。解决方案是通过BDC_OKCODE显式触发翻页(如=P+),并配合行号拼接(如(01)~(05))将数据写入不可见行。文中提供了完整的ABAP程序示例,展示了如何读取外部文件、动态生成BDCDATA、处理表格翻页逻辑,最终通过CALL TRANSACTION执行XK01事

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 272

十大经典排序算法之归并排序(Merge Sort)

归并排序(Merge Sort) 1945年由约翰·冯·诺伊曼(John von Neumann)首次提出 执行流程 ①、不断地将当前序列平均分割成2个子序列 ✓ 直到不能再分割(序列中只剩1个元素) ②、不断地将2个子序列合并成一个有序序列 ✓ 直到最终只剩下1个有序序列 (1)归并排序 — divide实现 @Override protected void sort() { leftArray = (T[]) new Comparable[array.length >> 1];

派拉斯兔子的博客 4192

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

归并排序(MERGE-SORT)

归并排序(MERGE-SORT) 1.基本介绍 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。 2.归并排序思想示意图 1、基本思想: 可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程 2、

xiaoshiguang3的博客 762

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

十大排序算法之归并排序

归并排序 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。 算法步骤 不断地将当前序列平均分割成2个子序列,直到不能再分割(序列中只剩1个元素) 不断地将2个子序列合并成一个有序序列,直到最终只剩下1个有序序列 divide实现 private E[] leftArray;

morris 1万+

VC中sqlite的使用

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

十大经典排序算法——归并排序(Merge Sort)

文章目录算法代码1-递归代码2-非递归 参考的文章: (1)这或许是东半球讲十大排序算法最好的一篇文章 (2)排序算法 - 面试中的排序算法总结 (3)必学十大经典排序算法,看这篇就够了 算法 (1)归并排序的核心思想是分治,分而治之,将一个大问题分解成无数的小问题进行处理,处理之后再合并,这里我们采用递归来实现; (2)时间复杂度O(nlogn) 代码1-递归 /** *...

Heorin X的博客 517

归并排序(Merge Sort)

归并排序(Merge Sort)是一种经典的排序算法,它采用分治法(Divide and Conquer)策略,将一个大数组分为两个小数组,分别进行排序,然后将这两个已排序的小数组合并成一个有序的大数组。归并排序在最坏情况下的时间复杂度为 O(nlog⁡n)O(nlogn),并且是一种稳定的排序算法。归并排序是一种高效且稳定的排序算法,适用于大规模数据的排序。通过分治法的思想,归并排序能够在最坏情况下保持 O(nlog⁡n)O(nlogn) 的时间复杂度。

Broken_x的博客 1396

【排序算法】归并排序(Merge Sort)

将两个的有序数列合并成一个有序数列,我们称之为"归并"。归并排序(Merge Sort)就是利用归并思想对数列进行排序。根据具体的实现,归并排序包括"从上往下"和"从下往上"2种方式。

DeveloperFire的博客 1628

Python排序算法(六)——归并排序(MERGE-SORT)

有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的pythonhttps://www.cnblogs.com/xxtalhr/p/10800699.html 一、归并排序(MERGE-SORT)概念   归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divi...

小麦粒的Python 1905

排序算法总结之归并排序 Merge Sort

算法原理: 归并排序使用分治的思想(divide and conquer): 1. 首先把数组平均分成两个子数组 2. 对两个字数组递归的使用归并排序进行排序 3. 把两个已经排好序的字数组合并得到结果 归并算法的原理图如下: 从图中可以看到归并排序把子问题的规模降低到1的时候停止,一个元素的数组一定是有序的。 算法伪代码: 伪代码来自算法导论归并排序算法部

fight to dead的博客 939

归并排序(Merge Sort)

归并排序(Merge Sort) ​ **归并排序(mergesort)的构思朴实而深刻,作为一个算法即古老又仍不失生命力。在排序算法的发展历史上,归并排序具有特殊的历史地位,它是第一个可以在最坏情况下依然保持O(nlogn)**运行时间的确定性排序算法。 ​ 无序向量的递归分解+有序向量的逐层合并(二路归并算法)。 1. int 类型 mergesort // 对arr中的[lo, hi)...

Tuffy 536
上一篇: 经典排序算法(四) —— Quick Sort 快速排序
下一篇: 经典排序算法(六) —— InsertionSort 插入排序
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值