【稳定且高效的分治排序 —— 归并排序算法】

news2024/9/27 4:45:25

【稳定且高效的分治排序 —— 归并排序算法】

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

归并排序的主要步骤包括分割和合并。分割是将待排序的数组不断分成较小的子数组,直到每个子数组只有一个元素,此时每个子数组都是有序的。合并则是将两个有序的子数组合并成一个更大的有序数组。
在这里插入图片描述

以下是用 Java 实现归并排序的代码示例:

public class MergeSort {
    // 将 arr(l...mid) 和 arr(mid+1...r) 两部分进行归并
    private static void merge(Comparable[] arr, int l, int mid, int r) {
        Comparable[] temp = new Comparable[r - l + 1];
        int i = l, j = mid + 1, k = 0;
        while (i <= mid && j <= r) {
            temp[k++] = (arr[i].compareTo(arr[j]) <= 0)? arr[i++] : arr[j++];
        }
        while (i <= mid) temp[k++] = arr[i++];
        while (j <= r) temp[k++] = arr[j++];
        for (i = l; i <= r; i++) arr[i] = temp[i - l];
    }
}

在 Python 中,归并排序可以这样实现:

def mergeSort(alist):
    if len(alist) > 1:
        mid = len(alist) // 2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]
        mergeSort(lefthalf)
        mergeSort(righthalf)
        i = j = k = 0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                alist[k] = lefthalf[i]
                i += 1
            else:
                alist[k] = righthalf[j]
                j += 1
            k += 1
        while i < len(lefthalf):
            alist[k] = lefthalf[i]
            i += 1
            k += 1
        while j < len(righthalf):
            alist[k] = righthalf[j]
            j += 1
            k += 1
    return alist

归并排序的时间复杂度为 O(n log n),空间复杂度为 O(n)。它的优点是稳定,适用于对稳定性有要求的排序场景。但缺点是需要额外的存储空间。归并排序在处理大规模数据时表现出色,尤其对于数据量较大且对稳定性有要求的情况,是一种可靠的排序算法选择。

归并排序算法步骤

归并排序是一种典型的分治算法应用。其步骤如下:
首先是分解阶段,将待排序的序列不断地分成两个部分,直到每个子序列只包含一个元素,此时认为子序列已经有序。例如对于序列{8, 6, 9, 5, 7},第一次分解为{8, 6, 9}{5, 7},再进一步分解为{8, 6}、{9}、{5}、{7}等。
接着是解决问题阶段,因为单个元素的子序列本身就是有序的,所以这个阶段在分解到最小子序列时自动完成。
最后是合并阶段,将两个有序的子序列合并成一个有序序列。比如将{8, 6}合并为{6, 8},将{5, 7}合并为{5, 7},再将{6, 8}{9}合并为{6, 8, 9},最后将{6, 8, 9}{5, 7}合并为{5, 6, 7, 8, 9}

在合并过程中,通常会创建一个临时数组来存储合并后的结果。比如有两个有序子序列 A 和 B,定义两个指针分别指向 A 和 B 的起始位置,同时创建一个辅助指针指向临时数组的起始位置。比较两个指针所指向的元素,较小的元素放入临时数组,对应的指针和辅助指针均向后移动一位。重复这个过程,直到某一指针到达序列尾。此时将另一序列剩下的所有元素直接复制到临时数组。最后,将临时数组中的元素填充回原数组。

归并排序算法优点

归并排序算法具有以下优点:

  1. 稳定性:归并排序保证了相等元素的相对顺序不变,适合于需要维持原有顺序的应用场景。例如在对包含多个相同元素的序列进行排序时,归并排序能够确保相同元素的先后顺序不发生改变。
  2. 时间复杂度稳定:无论输入数据是否已经部分有序,归并排序都能确保最坏、最好和平均时间复杂度均为 O(n log n),具有较好的平均和最坏情况下的性能表现。这使得归并排序在处理各种不同类型的数据时都能保持较为高效的性能。
  3. 适用大规模数据:尽管归并排序由于需要额外空间进行合并可能不适合内存受限的情况,但在处理大文件或流式数据时,可通过外部存储辅助完成排序(外排序)。例如在处理大规模数据集时,可以将数据分成小块进行排序,然后再逐步合并,从而有效地处理大规模数据。
  4. 逻辑清晰:归并排序算法思路简洁明了,易于理解和实现,有助于初学者掌握分治策略的核心思想。其分解、解决和合并的步骤明确,使得程序员在实现该算法时能够清晰地把握整个过程。

归并排序算法缺点

归并排序算法存在以下缺点:

  1. 空间复杂度高:归并排序需要额外的空间来存储临时数组,其空间复杂度为 O(n)。在处理大规模数据时,这可能会占用大量的内存空间,特别是在内存受限的环境下,可能会导致性能问题。
  2. 不是原地排序:与一些原地排序算法相比,归并排序需要额外的空间来完成排序过程,不能在原数组上直接进行排序操作。这在一些对内存空间要求严格的场景下可能不太适用。

总结

归并排序算法作为一种经典的排序算法,具有稳定性、时间复杂度稳定等优点,适用于各种数据类型和数据量的排序任务。然而,其空间复杂度较高的缺点也需要在实际应用中加以考虑。在选择排序算法时,应根据具体的应用场景和需求来综合考虑归并排序算法的优缺点,以选择最合适的排序算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2168788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度探索与实战编码:利用Python与AWS签名机制高效接入亚马逊Product Advertising API获取商品详情

亚马逊商品详情接口技术贴及代码示例 在电商数据分析和产品管理中&#xff0c;获取商品的详细信息是至关重要的一环。亚马逊作为全球领先的电商平台&#xff0c;提供了丰富的商品数据和强大的API接口&#xff0c;使得开发者能够轻松获取商品的详细信息。本文将详细介绍如何使用…

NASA:ATLAS/ICESat-2 L3 A沿线内陆地表水数据V006数据集

目录 简介 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3A Along Track Inland Surface Water Data V006 简介 ATLAS/ICESat-2 L3 A沿线内陆地表水数据V006 ATLAS/ICESat-2 L3 A沿线内陆地表水数据V006是指由ATLAS/ICESat-2卫星获取的针对陆地…

矿石运输船数据集、散货船数据集、普通货船数据集、集装箱船数据集、渔船数据集以及客船数据集

海船&#xff1a;用于船只检测的大规模精准标注数据集 我们很高兴地介绍一个新的大规模数据集——海船&#xff0c;该数据集专为训练和评估船只目标检测算法而设计。目前&#xff0c;这个数据集包含31,455张图像&#xff0c;并涵盖了六种常见的船只类型&#xff0c;包括矿石运…

en造数据结构与算法C# 二叉排序树 泛型类的基本构成

前置知识&#xff1a;二叉树 en造数据结构与算法C# 二叉树的顺序存储和前中后序遍历-CSDN博客 二叉排序树基本规则 二叉排序树的特点就是有序&#xff0c;其基本规则分为两个点 1.按照顺序去存储节点(下图绿色的顺序) 2.其次&#xff0c;在第一点的基础上&#xff0c;比…

python之装饰器、迭代器、生成器

装饰器 什么是装饰器&#xff1f; 用来装饰其他函数&#xff0c;即为其他函数添加特定功能的函数。 装饰器的两个基本原则&#xff1a; 装饰器不能修改被装饰函数的源码 装饰器不能修改被装饰函数的调用方式 什么是可迭代对象&#xff1f; 在python的任意对象中&#xff…

Centos 7.9 Kubeadm安装k8s1.20.11

一、环境 主机用途192.168.76.140k8s-master1192.168.76.141k8s-node1 二、设置yum源 由于系统已经关闭&#xff0c;可以用centos9尝试 cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak vi /etc/yum.repos.d/CentOS-Base.repo# 使用阿里云的y…

ARM基础架构-文档导读系列

第一章 简介 Introducing the Arm architecture 第二章 指令集 Armv8-A Instruction Set ArchitectureLearn the architecture -A64 Instruction Set Architecture 第三章 指令集 ARM异常模型GICv3 v4 overviewGeneric Interrupt Controller v3 and v4, VirtualizationArm…

皮肤病检测-目标检测数据集(包括VOC格式、YOLO格式)

皮肤病检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1XNTo-HsBCHJp2UA-dpn5Og?pwdlizo 提取码&#xff1a;lizo 数据集信息介绍&#xff1a; 共有 2025 张图像和一一对应的标注文件 标注文件格式提供…

工作安排 - 华为OD统一考试(E卷)

2024华为OD机试(C卷+D卷)最新题库【超值优惠】Java/Python/C++合集 题目描述 小明每周上班都会拿到自己的工作清单,工作清单内包含n项工作,每项工作都有对应的耗时时长(单位h)和报酬,工作的总报酬为所有已完成工作的报酬之和。那么请你帮小明安排一下工作,保证小明在指定…

说说海外云手机的自动化功能

在全球社交媒体营销中&#xff0c;通过自动化功能&#xff0c;企业不再需要耗费大量时间和精力手动监控和操作每台设备。这意味着&#xff0c;企业可以显著提升效率、节省成本&#xff0c;同时减少对人力资源的依赖。那么&#xff0c;海外云手机的自动化功能具体能带来哪些优势…

Linux云计算 |【第四阶段】NOSQL-DAY3

主要内容&#xff1a; redis主从复制、哨兵服务&#xff08;高可用&#xff09;、数据持久化&#xff08;RDB、AOF&#xff09; 一、Redis主从复制概述 Redis 主从复制是一种数据复制机制&#xff0c;用于在多个 Redis 实例之间同步数据&#xff0c;以提高系统的可用性、可靠…

JVM(HotSpot):方法区(Method Area)

文章目录 一、内存结构图二、方法区定义三、内存溢出问题四、常量池与运行时常量池 一、内存结构图 1.6 方法区详细结构图 1.8方法区详细结构图 1.8后&#xff0c;方法区是JVM内存的一个逻辑结构&#xff0c;真实内存用的本地物理内存。 且字符串常量池从常量池中移入堆中。 …

Actions Speak Louder than Words Meta史诗级的端到端推荐大模型落地

发现好久之前整理的推荐系统被遗忘在了草稿箱&#xff0c;让它出来见见世面。。。后续空了持续更新 文章目录 1.Background2.Related works2.1 典型推荐模型2.1.1 DIN2.1.2 DIEN2.1.3 SIM2.1.4 MMoE2.1.5 其他 2.2. 生成式推荐 3.Method3.1 统一特征空间3.2 重塑召回排序模型3.…

MySQL 面试题及答案

MySQL 面试题及答案&#xff1a; 一、基础问题 什么是数据库索引&#xff1f;有哪些类型&#xff1f; 答&#xff1a;数据库索引是一种数据结构&#xff0c;用于提高数据库查询的效率。它就像一本书的目录&#xff0c;可以快速定位到特定的数据行。 类型主要有&#xff1a; …

C++实现二叉树的创建删除,dfslfs,求叶子结点个数,求叶子结点个数,求树的高度

C实现二叉树的创建删除&#xff0c;dfs/lfs,求叶子结点个数&#xff0c;求树的高度 基本算法&#xff1a; 用链栈建立二叉树&#xff0c;通过递归实现深度优先的三种遍历&#xff0c;用队列实现广度优先层次遍历。借助递归思想求解叶子结点个数和树的深度。 tree.h定义基本的…

sysbench 命令:跨平台的基准测试工具

一、命令简介 sysbench 是一个跨平台的基准测试工具&#xff0c;用于评估系统性能&#xff0c;包括 CPU、内存、文件 I/O、数据库等性能。 ‍ 比较同类测试工具 bench.sh 在上文 bench.sh&#xff1a;Linux 服务器基准测试中介绍了 bench.sh 一键测试脚本&#xff0c;它对…

CAT1 RTU软硬件设计开源资料分析(TCP协议+Modbus协议+GNSS定位版本 )

01 CAT1 RTU方案简介&#xff1a; 远程终端单元( Remote Terminal Unit&#xff0c;RTU)&#xff0c;一种针对通信距离较长和工业现场环境恶劣而设计的具有模块化结构的、特殊的计算机测控单元&#xff0c;它将末端检测仪表和执行机构与远程控制中心相连接。 奇迹TCP RTUGNS…

【MySQL】数据库--索引

索引 1.索引 在数据中索引最核心的作用就是&#xff1a;加速查找 1.1 索引原理 索引的底层是基于BTree的数据存储结构 如图所示&#xff1a; 很明显&#xff0c;如果有了索引结构的查询效率比表中逐行查询的速度要快很多且数据越大越明显。 数据库的索引是基于上述BTree的…

C--结构体和位段的使用方法

各位看官如果您觉得这篇文章对您有帮助的话 欢迎您分享给更多人哦 感谢大家的点赞收藏评论&#xff0c;感谢您的支持&#xff01;&#xff01;&#xff01; 一&#xff1a;结构体 首先结构体我们有一个非常重要的规则 非常重要&#xff1a; 我们允许在初始化时自动将字符串字面…

Jmeter关联,断言,参数化

一、关联 常用的关联有三种 1.边界提取器 2.JSON提取器 3.正则表达式提取器 接下来就详细讲述一下这三种的用法 这里提供两个接口方便练习 登录接口 接口名称&#xff1a;登录 接口提交方式&#xff1a;POST 接口的url地址&#xff1a;https://admin-api.macrozheng.com/a…