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

排序算法—sort(),stable_sort(),merge() 排序目录:一.sort()二.stable_sort()三.merge()1.merge函数的作用:2.为什么引入归并排序merge()函数3.代码4.例题P1309 瑞士轮 一.sort() cppreference中的详细解释 二.stable_sort() stable_sort()遇见大小相同的值不会改变他们的位置 cppreference中的详细解释 三.merge() cpprefer... 阅读详情

算法原理

归并排序的核心思想是将一个大的数组分割成多个小的子数组,然后分别对这些子数组进行排序,最后将排序后的子数组合并起来,得到一个有序的大数组。

算法描述

归并排序(Merge Sort)是一种经典的排序算法,其原理基于分治(Divide and Conquer)策略。它的核心思想是将一个大问题分割成多个小问题,解决小问题后再将它们合并以得到最终结果。

具体步骤如下:

  1. 分割(Divide):将待排序的数组递归地分割成两个子数组,直到每个子数组只包含一个元素。

  2. 排序(Conquer):对每个子数组进行排序,通常使用递归来排序。

  3. 合并(Merge):将排好序的子数组合并成一个新的有序数组。

  4. 重复步骤2和步骤3,直到整个数组都被排序。

动画演示

在这里插入图片描述

代码实现

 public static void mergeSort(int[] array) {
        if (array == null || array.length <= 1) {
            return; // 如果数组为空或只有一个元素,无需排序
        }
        int[] temp = new int[array.length]; // 创建一个临时数组来辅助排序
        mergeSort(array, 0, array.length - 1, temp); // 调用归并排序函数
    }

    private static void mergeSort(int[] array, int left, int right, int[] temp) {
        //直到每个子数组只包含一个元素 即:left == right
        //也就是说最小排序单位是长度为2的数组,当长度为2时,此时无法再递归,而进行排序
        if (left < right) {
            int mid = (left + right) / 2;
            // 对左半部分进行归并排序
            mergeSort(array, left, mid, temp);
            // 对右半部分进行归并排序
            mergeSort(array, mid + 1, right, temp);
            // 合并两个有序数组
            merge(array, left, mid, right, temp);
        }
    }

    private static void merge(int[] array, int left, int mid, int right, int[] temp) {
        int i = left; // 左数组的起始索引
        int j = mid + 1; // 右数组的起始索引
        int k = left; // 临时数组的起始索引

        // 比较左右两个数组的元素,将较小的元素放入临时数组
        while (i <= mid && j <= right) {
            if (array[i] <= array[j]) {
                temp[k++] = array[i++];
            } else {
                temp[k++] = array[j++];
            }
        }

        // 将左数组剩余部分复制到临时数组
        while (i <= mid) {
            temp[k++] = array[i++];
        }

        // 将右数组剩余部分复制到临时数组
        while (j <= right) {
            temp[k++] = array[j++];
        }

        // 将临时数组的元素复制回原数组
        for (i = left; i <= right; i++) {
            array[i] = temp[i];
        }
    }

算法复杂度

时间复杂度(最坏)时间复杂度(最好)时间复杂度(平均)空间复杂度稳定性
O(n log n)O(n log n)O(n log n)O(n)稳定
  • 平均时间复杂度为 O(n log n),其中 n 是待排序数组的大小。

  • 最好情况和最坏情况下的时间复杂度也都是 O(n log n)。

  • 归并排序需要额外的空间来存储临时数组,在最坏情况下需要与输入数组一样大的空间,因此空间复杂度是 O(n)。

归并排序的优化方式

上述代码实现了基本的归并排序算法,但它在合并过程中存在一个潜在的优化点。在归并排序的合并阶段,将左右两个有序数组合并为一个有序数组时,可以通过判断左边数组的最大值和右边数组的最小值来优化合并操作,避免不必要的比较。

这个优化点可以通过添加一个条件来判断是否需要合并,如果左边数组的最大值小于等于右边数组的最小值,则无需合并,因为两个数组已经是有序的,不需要进行额外的比较和移动。

private static void merge(int[] array, int left, int mid, int right, int[] temp) {
    int i = left; // 左数组的起始索引
    int j = mid + 1; // 右数组的起始索引
    int k = left; // 临时数组的起始索引

    // 如果左数组的最大值小于等于右数组的最小值,则无需合并,直接返回
    if (array[mid] <= array[j]) {
        return;
    }

    // 比较左右两个数组的元素,将较小的元素放入临时数组
    while (i <= mid && j <= right) {
        if (array[i] <= array[j]) {
            temp[k++] = array[i++];
        } else {
            temp[k++] = array[j++];
        }
    }

    // 将左数组剩余部分复制到临时数组
    while (i <= mid) {
        temp[k++] = array[i++];
    }

    // 将右数组剩余部分复制到临时数组
    while (j <= right) {
        temp[k++] = array[j++];
    }

    // 将临时数组的元素复制回原数组
    for (i = left; i <= right; i++) {
        array[i] = temp[i];
    }
}

这个优化逻辑在判断左右两个子数组已经有序时,可以避免不必要的比较和赋值操作,提升归并排序的性能。

归并排序核心就是 递归,分治,记住这两个词就能大致理解这个算法,递归思想真的很重要,不容易完全理解,还得继续练习-_-


相关概念
• 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
• 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
• 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
• 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

使用C#详解常用排序算法(三):归并排序(Merge Sort) 结合C#代码讲解归并排序。 阅读详情

相关推荐

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

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

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

11.6 归并排序

合并阶段”从底至顶地将左子数组和右子数组合并为一个有序数组。需要注意的是,从长度为 1 的子数组开始合并,合并阶段中的每个子数组都是有序的。是一种基于分治策略的排序算法,包含图 11-10 所示的“划分”和“合并”阶段。如图 11-11 所示,“划分阶段”从顶至底递归地将数组从中点切分为两个子数组。具体实现细节比较复杂,有兴趣的读者可以查阅相关资料进行学习。观察发现,归并排序与二叉树后序遍历的递归顺序是一致的。对于链表,归并排序相较于其他排序算法具有显著优势,归并排序的实现如以下代码所示。

让学习成为一种习惯 1242

基于C++的Merge Sort分治排序算法实战详解

当数据无法全部加载进内存时(如 TB 级日志文件),Merge Sort 成为核心组件。流程如下:分批读取固定大小的数据块内存中排序后写回临时文件执行多路归并,逐段读取各文件头部,输出有序结果此方法广泛应用于数据库引擎、搜索引擎索引构建等系统。

weixin_36382073的博客 1123

排序算法 - 归并排序详解

基本介绍 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。 基本思想 将序列中待排序数字分为若干组,最终每个数字分为一组。(默认长度为1的序列是有序的) 将若干个组两两合并,保证合并后的组是有序的。(俩个子序列头部进行比较大小) 重复第二步操作直到只剩下一组,排序完成。 归并排序思想示

张大安的博客 4931

merge sort 算法的C++实现

merge sort 排序 C++ merge sort 算法的C++实现

Merge Sort 算法 C语言实现

Merge Sort 算法的C语言实现 linux 下编译;windows下没试过,也许需要改头文件

一文读懂『归并排序』算法(Merge Sort)

归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用 分治法(Divide and Conquer) 的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

专注自动化、性能测试、测试架构学习交流 6712

合并排序算法——merge sort

#include <stdio.h> #include <malloc.h> #include <limits.h> void init(int A[],int p,int r);//初始化数组 void print_A(int A[],int p,int r);//打印数组元素 void merge(int A[],int p,int q,int r);//合并排序算法 /************合并排序算法的实现******************/ int main() { int p,q,r; printf("合并排序算法的实现:\n"); printf("请输入p、q、r的值(输入格式1,12,13):"); scanf("%d,%d,%d",&p,&q,&r); printf("p=%d,q=%d,r=%d\n",p,q,r); int * A = (int*)malloc((r+1)*sizeof(int)); init(A,p,r); printf("待合并数组:\n"); print_A(A,p,r); printf("\n\n"); printf("合并排序算法的实现过程:\n"); merge(A,p,q,r); free(A);//释放动态数组空间 return 0; }

归并排序

归并排序 “归并”的含义是将两个或者两个以上的有序表组合成一个新的有序表。假设待排序表含有n个记录,则可以看成n个有序的子表,每个子表长度为1,然后两两归并,得到 n/2 个长度为2或者1的有序表;再两两归并,直到合并成一个长度为n的有序表为止,这种排序方法称为 2-路归并排序。 递归的2-路归并排序算法是基于分治算法的 ,以O(NlogN)最坏情形时间运行,而所使用的比较次数几乎是最优的...

一个小白的成长之路 4908

mergesort

基于c++的归并排序算法。排序算法大体可分为两种:     一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。     另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。

nnDetection实战:手把手教你用Python在自家电脑上跑通第一个肺结节检测模型

本文详细介绍了如何使用nnDetection框架在普通电脑上实现肺结节检测模型的搭建与运行。从环境配置、数据预处理到模型训练与推理,手把手教你完成医学图像检测的全流程,特别适合初学者入门医学AI领域。

weixin_32377497的博客 330

图解排序算法及实现——归并排序 (Merge Sort)

思路 归并排序(MergeSort),是创建在归并操作上的一种有效的排序算法,效率为O(nlogn) 。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。 实现 递归法: 自顶向下(Top-Down) 直接在原序列上直接归并排序,每次归并排序分别对左右两边进行归并排序,直至细分到两两分组。 ...

张渊猛的博客 4万+

【一起学UniGUI】--UniGUI的部署选项(5)

uniGUI支持Windows平台下所有主要部署选项。 1.Standalone Server (独立服务器) 最简单的部署方法是独立服务器。在这种模式下,应用程序服务器像桌面应用程序一样直接运行。它也是用于调试应用程序的模式。运行应用程序可执行文件后(它是一个EXE文件),它将最小化到托盘图标,并运行到用户手动终止为止。见下图: 一个独立的应用程序可以...

5776

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

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

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

闲置服务器之代理服务器篇

这台服务器是在阿里云免费白嫖的,天工开物计划,阿里给的300块无门槛优惠券,买了一台新加坡的境外服务器,288,刚刚抵扣完,因为是境外服务器,能够访问一些国内不能访问的网站,所以本文章仅从技术的角度来搭建代理服务器,使用时,请自觉遵守国家相关规定,如有任何违法行为,与本人无任何关系!!!。本文使用tinyproxy来搭建代理服务器。

m0_50281408的博客 2104

海波龙(Hyperion,现属 Oracle)合并报表以 HFM(Hyperion Financial Management)为核心系统,方法论核心是以控制为基础确定合并范围,通过维度建模统一数据口径

摘要:海波龙合并报表系统(HFM)采用"规则驱动、维度建模"的方法论,通过四个核心环节实现自动化合并:确定合并范围、数据标准化、自动抵销调整及报表生成。系统支持多会计准则,以控制为基础划分合并方法(完全合并/权益法/成本法),通过维度建模统一数据口径,自动处理内部交易抵销、外币折算等复杂操作。业务操作流程涵盖数据采集、转换、抵销调整到报表生成全过程,关键控制点包括内部交易匹配、股权变动处理等。最终输出合规合并报表及完整审计线索,满足监管与管理需求。(150字)

金牌架构师 1302

十大经典排序算法之归并排序(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];

派拉斯兔子的博客 4191

FPGA纯Verilog实现I²C主机控制器与EEPROM读写

I²C是一种广泛应用的同步串行总线协议,用于连接微控制器与EEPROM、传感器等低速外设。其核心原理包括开漏结构、主从通信机制、START/STOP时序及ACK/NACK应答流程。技术价值在于硬件资源占用少、布线简洁、支持多从机扩展,特别适合FPGA嵌入式系统中轻量级外设控制。典型应用场景涵盖工业数据存储、配置参数持久化及实时传感器接口。本文基于Xilinx Spartan-6 FPGA,采用纯Verilog HDL实现参数化I²C主机控制器与AT24C02 EEPROM读写验证,深入解析状态机设计、SDA

weixin_33557333的博客 119

十大排序算法之归并排序

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

morris 1万+

SAP_SD模块路径及运输功能后台配置简介

后台路径:SPRO—后勤执行—装运—基本发运功能—定义路线—定义传输模式根据实际运输过程运输地理的类型:海运、公路运输、空运后台路径:SPRO—后勤执行—装运—基本发运功能—定义路线—定义发运类型根据实际运输过程运输方式:汽车、卡车、火车、轮船、飞机后台路径:SPRO—后勤执行—装运—基本发运功能—路径—定义路线—定义运输连接点指在运输过程中需要中转的地区可以维护中转地区的停留的时间后台路径:SPRO—后勤执行—装运—基本发运功能—路径—定义路线—定义路径和阶段。

我小时候很黑的博客 1395

Fiori Elements 从入门到精通开发教程的文章目录

Fiori Elements 开发技术相对 SAP 其他历史悠久,发展成熟的开发技术来说,是一个新事物。正因如此,迄今为止国内深入讲解 Fiori Elements 应用的中文材料几乎没有。

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

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

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

Heorin X的博客 517

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

Visual Studio 2022+Qt6.5.3安装教程+环境配置+创建Qt项目+乱码插件+运行很完美(16岁孩子也能看懂)

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 1189

归并排序(MERGE-SORT)

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

xiaoshiguang3的博客 762

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【内部排序】八:归并排序(Merge Sort)详解与代码

归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。最简单的归并是直接将两个有序的子表合并成一个有序的表。   2-路归并排序 在内部排序中,通常采用的是2-路归并排序。即:将含有n个元素的序列看成是n个有序的子序列,每个子序列的长度为1,而后两两合并,得到n/2个长度为2或1的有序子序列,再进行两两合并。。。直到最后由两个有序的子序列合并成为一个长度为n的有序序列。2-路归并的核心操

牧之 4347

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Thrust排序算法完全指南:radix sort、merge sort与stable sort对比

Thrust是NVIDIA推出的C++并行算法库,提供了高效的GPU加速排序功能。在Thrust中,**radix sort(基数排序)**、**merge sort(归并排序)** 和 **stable sort(稳定排序)** 是最核心的三种排序算法,每种都有其独特的优势和应用场景。 ## 📊 三种排序算法核心特点对比 ### Radix Sort(基数排序) **radix sort*

gitblog_00949的博客 783

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: 详解十大经典排序算法(四):希尔排序(Shell Sort)
下一篇: 详解十大经典排序算法(六):快速排序(QuickSort)
_蓝橙
博客等级 码龄7年 1179粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值