news 2026/3/24 15:30:03

归并排序的核心逻辑是基于**分治法**的思想,将一个大问题分解为若干个相同结构的小问题来解决

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
归并排序的核心逻辑是基于**分治法**的思想,将一个大问题分解为若干个相同结构的小问题来解决

归并排序的核心逻辑是基于分治法的思想,将一个大问题分解为若干个相同结构的小问题来解决。具体流程如下:

  1. 分解阶段:将待排序数组不断二分,直到每个子数组只包含一个元素(单个元素天然有序);
  2. 合并阶段:通过Merge函数将两个有序的子数组合并成一个新的有序数组;
  3. 递归回溯:随着递归返回,较小的有序段被逐步合并为更大的有序段,最终形成整个有序数组。

核心操作:Merge函数(以两路归并为例)

defmerge(arr,left,mid,right):# 创建临时数组存储左右两部分left_arr=arr[left:mid+1]right_arr=arr[mid+1:right+1]i=j=0# 左右子数组的指针k=left# 原数组中的位置# 按升序将元素复制回原数组whilei<len(left_arr)andj<len(right_arr):ifleft_arr[i]<=right_arr[j]:arr[k]=left_arr[i]i+=1else:arr[k]=right_arr[j]j+=1k+=1# 复制剩余元素whilei<len(left_arr):arr[k]=left_arr[i]i+=1k+=1whilej<len(right_arr):arr[k]=right_arr[j]j+=1k+=1

递归实现:MSort函数

defmsort(arr,left,right):ifleft<right:mid=(left+right)//2msort(arr,left,mid)# 递归排序左半部分msort(arr,mid+1,right)# 递归排序右半部分merge(arr,left,mid,right)# 合并已排序的两部分

归并排序性能分析

  • 时间复杂度:始终为 $ O(n \log n) $,无论最好、最坏或平均情况;
  • 空间复杂度:$ O(n) $,需要额外的辅助空间用于合并过程;
  • 稳定性:稳定排序算法(相等元素的相对位置不会改变);
  • 是否原地:非原地排序(需要额外内存);
  • 适用场景:适合对稳定性有要求且数据量较大的排序任务,如外部排序。
  • 非递归版本的归并排序(也称自底向上的归并排序)不使用递归来分解数组,而是从最小粒度(长度为1的子数组)开始,逐步合并成更大的有序段,直到整个数组有序。

实现思路:

  1. 初始时,将每个元素看作一个长度为1的有序子数组;
  2. 每次将相邻的两个有序子数组进行两路归并,形成长度为2、4、8……的有序段;
  3. 使用循环控制当前要合并的子数组长度(size),每次翻倍;
  4. 在每一趟中遍历整个数组,对每一对相邻子数组调用merge函数合并。

Python代码实现(非递归归并排序)

defmerge(arr,left,mid,right):# 辅助函数:合并 arr[left..mid] 和 arr[mid+1..right]temp=[]i,j=left,mid+1# 双指针合并两个有序部分whilei<=midandj<=right:ifarr[i]<=arr[j]:temp.append(arr[i])i+=1else:temp.append(arr[j])j+=1# 复制剩余元素whilei<=mid:temp.append(arr[i])i+=1whilej<=right:temp.append(arr[j])j+=1# 回写到原数组foridx,valinenumerate(temp):arr[left+idx]=valdefmerge_sort_iterative(arr):n=len(arr)size=1# 当前子数组的长度(从1开始,逐步翻倍)whilesize<n:# 对每一对长度为 size 的子数组进行合并forleftinrange(0,n,2*size):mid=min(left+size-1,n-1)right=min(left+2*size-1,n-1)# 如果 mid < right,说明有两个子数组可以合并ifmid<right:merge(arr,left,mid,right)size*=2# 子数组长度翻倍

示例演示:

data=[38,27,43,3,9,82,10]merge_sort_iterative(data)print(data)# 输出: [3, 9, 10, 27, 38, 43, 82]

特点分析:

  • 无需递归栈:避免了递归带来的函数调用开销和栈溢出风险;
  • 时间复杂度:仍为 $ O(n \log n) $,共需 $ \lceil \log_2 n \rceil $ 趟归并,每趟耗时 $ O(n) $;
  • 空间复杂度:$ O(n) $,用于临时数组;
  • 适用场景:适合栈空间受限或需要完全可控迭代过程的系统中。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/16 23:24:06

跨境电商卖家必备:亚马逊商品描述多语言OCR翻译工作流

跨境电商卖家必备&#xff1a;亚马逊商品描述多语言OCR翻译工作流 在跨境电商的日常运营中&#xff0c;一个看似微不足道却频繁发生的痛点正在悄然吞噬卖家的时间与利润——如何快速、准确地将本地语言的商品信息转化为目标市场的语言&#xff1f;尤其是当这些信息以图像形式存…

作者头像 李华
网站建设 2026/3/7 13:23:16

PHP表单数据处理深度解析:GET与POST方法的选择、实践与安全策略

在Web开发领域&#xff0c;表单是用户与服务器进行交互的核心桥梁。作为服务器端脚本语言的翘楚&#xff0c;PHP提供了强大而灵活的功能来处理表单提交的数据。其中&#xff0c;GET和POST是最基础且最关键的两种HTTP请求方法。对这两种方法的深刻理解、正确选择和安全使用&…

作者头像 李华
网站建设 2026/3/23 16:34:55

交通违章取证:违停汽车前挡风玻璃罚单OCR结构化存储

交通违章取证&#xff1a;违停汽车前挡风玻璃罚单OCR结构化存储 在一线交警的日常执法中&#xff0c;一个看似简单却极其耗时的任务正悄然发生——对违停车辆张贴罚单后&#xff0c;逐字抄录信息、手动录入系统。这一过程不仅效率低下&#xff0c;还容易因光线不佳、字迹模糊或…

作者头像 李华
网站建设 2026/3/20 4:32:25

腾讯混元OCR vs 传统OCR:为什么轻量级模型更高效?

腾讯混元OCR vs 传统OCR&#xff1a;为什么轻量级模型更高效&#xff1f; 在文档数字化需求爆发的今天&#xff0c;企业每天要处理成千上万张发票、身份证、合同和扫描件。传统的OCR系统虽然早已普及&#xff0c;但面对复杂排版、多语言混合、实时响应等新挑战时&#xff0c;常…

作者头像 李华
网站建设 2026/3/24 8:15:46

C语言学习练习基础

作业一练习一输入某一天的年月日&#xff0c;输出下一天的年月日。#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <stdbool.h> int daysOfMonth[13] { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; //判断某一年是否为闰年 bool isLeapYear(int year…

作者头像 李华
网站建设 2026/3/24 2:19:19

vue+uniapp+springboot基于微信小程序的校园互助论坛学习社区95l77

文章目录项目概述核心功能技术亮点应用场景主要技术与实现手段系统设计与实现的思路系统设计方法java类核心代码部分展示结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;项目概述 基于微信小程序的校园互助论坛学习社区&#xff08;项…

作者头像 李华