news 2026/4/14 20:38:57

归并排序和基数排序是两种重要的排序算法,各自基于不同的思想实现高效、稳定的排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
归并排序和基数排序是两种重要的排序算法,各自基于不同的思想实现高效、稳定的排序

归并排序和基数排序是两种重要的排序算法,各自基于不同的思想实现高效、稳定的排序。


一、归并排序(Merge Sort)

核心逻辑:分治法

  • 分解:将待排序数组从中间分割为两个子数组,递归地对左右两部分进行排序。
  • 合并:使用Merge函数将两个已排序的子数组合并成一个有序数组。
关键函数说明:
voidMSort(intdata[],ints,intt){if(s<t){intm=(s+t)/2;MSort(data,s,m);// 排序左半部分MSort(data,m+1,t);// 排序右半部分Merge(data,s,m,t);// 合并两个有序段}}
  • Merge(data, s, m, t)实现:
    • 创建临时数组暂存原数组片段
    • 使用双指针分别遍历左半[s, m]和右半[m+1, t]
    • 按升序将较小元素复制到结果中
    • 复制剩余元素
    • 将临时数组内容拷贝回原数组
入口函数:
voidMergeSort(intdata[],intn){MSort(data,0,n-1);}
  • 时间复杂度:O(n log n),无论最好、最坏、平均情况
  • 空间复杂度:O(n) —— 需要额外的临时数组用于合并
  • 稳定性:稳定(相等元素相对位置不变)
  • 适用场景:要求稳定排序或链表排序时表现优异

二、基数排序(Radix Sort)

基本思想:按位排序 + 分配收集

将整数视为由多个“位”组成的数字串(如十进制下个、十、百位),从最低位开始逐位排序。

排序步骤:
  1. 设定 r 个队列(例如 r=10 对应数字 0~9)
  2. 从最低有效位(LSD)开始处理每一位:
    • 分配:根据当前位上的数值,把每个数放入对应编号的队列中
    • 收集:按队列 0→r-1 的顺序取出所有元素,形成新的序列
  3. 重复上述过程直到最高位处理完毕

示例:排序 [170, 45, 75, 90, 2, 802, 24]

第一次(个位)后:[170, 90, 2, 802, 24, 45, 75]
第二次(十位)后:[2, 802, 24, 45, 75, 170, 90]
第三次(百位)后:[2, 24, 45, 75, 90, 170, 802]

特性分析:
  • 稳定性:稳定 —— 队列先进先出保证相同关键字顺序不乱
  • 时间复杂度:O(d(n + r))
    • d:最大数的位数(如最大为999,则d=3)
    • n:元素个数
    • r:基数(如十进制r=10)
  • 空间复杂度:O(r + n)
    • 需要 r 个队列头尾指针(链式队列)
    • 每个元素需存储指针(若用链表结构)
应用场景:
  • 整数排序(尤其是固定位宽的键值,如电话号码、身份证号)
  • 外部排序中的辅助手段
  • 当 d 较小且 r 不大时效率很高,可达到线性时间趋势

总结对比:

特性归并排序基数排序
排序依据比较元素大小按位分配
是否比较排序
时间复杂度O(n log n)O(d(n + r))
空间复杂度O(n)O(n + r)
稳定性稳定稳定
适用数据类型可比较任意对象数字、字符串等可分解关键字
最佳应用场景要求稳定、通用性强数据范围集中、位数少

归并排序中的Merge函数是核心操作,用于将两个已排序的子数组合并为一个有序数组。以下是完整的 C 语言代码实现,包含详细注释:

#include<stdio.h>#include<stdlib.h>// 合并函数:将 data[s..m] 和 data[m+1..t] 两个有序子数组合并为有序数组voidMerge(intdata[],ints,intm,intt){intn1=m-s+1;// 左半部分长度intn2=t-m;// 右半部分长度// 动态分配临时数组存储左右两部分int*left=(int*)malloc(n1*sizeof(int));int*right=(int*)malloc(n2*sizeof(int));if(!left||!right){printf("内存分配失败\n");exit(1);}// 复制数据到临时数组for(inti=0;i<n1;i++)left[i]=data[s+i];for(intj=0;j<n2;j++)right[j]=data[m+1+j];// 归并过程:双指针法合并inti=0,j=0,k=s;while(i<n1&&j<n2){if(left[i]<=right[j]){// 使用 <= 保证稳定性data[k++]=left[i++];}else{data[k++]=right[j++];}}// 复制剩余元素while(i<n1)data[k++]=left[i++];while(j<n2)data[k++]=right[j++];// 释放临时内存free(left);free(right);}// 递归分治排序voidMSort(intdata[],ints,intt){if(s<t){intm=s+(t-s)/2;// 防止整数溢出MSort(data,s,m);MSort(data,m+1,t);Merge(data,s,m,t);}}// 入口函数:对长度为 n 的数组进行归并排序voidMergeSort(intdata[],intn){MSort(data,0,n-1);}// 示例测试程序intmain(){intarr[]={38,27,43,3,9,82,10};intn=sizeof(arr)/sizeof(arr[0]);printf("排序前: ");for(inti=0;i<n;i++)printf("%d ",arr[i]);printf("\n");MergeSort(arr,n);printf("排序后: ");for(inti=0;i<n;i++)printf("%d ",arr[i]);printf("\n");return0;}

输出结果:

排序前: 38 27 43 3 9 82 10 排序后: 3 9 10 27 38 43 82

关键点说明:

  • 临时数组:使用malloc分配空间暂存左右子数组,避免覆盖。
  • 稳定性保障:合并时使用<=判断,确保相等元素保持原有顺序。
  • 边界处理:正确计算索引范围[s..m][m+1..t]
  • 资源管理:及时释放动态分配的内存。

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

vue基于 SpringBoot 的会议室意见收集投票管理系统

目录 系统概述核心功能技术实现应用价值 开发技术 核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 系统概述 该…

作者头像 李华
网站建设 2026/4/10 21:51:24

影视配音初探:低成本完成外语影片本地化尝试

影像之声的重塑&#xff1a;用AI实现低成本外语影片中文配音 在流媒体平台日更千集的时代&#xff0c;我们每天都在消费来自世界各地的影视内容。然而&#xff0c;真正能跨越语言鸿沟、完整传递情绪与语境的作品却依然稀缺。传统配音流程动辄需要数周时间、数十万元预算——录音…

作者头像 李华
网站建设 2026/4/12 6:50:19

极致画质背景素材库

引言&#xff1a;定义画面的视觉基调一个高质量、高分辨率的背景视频&#xff0c;是构建专业视觉作品的基石。无论是发布会主视觉、线上课程背景&#xff0c;还是高端品牌展示&#xff0c;超高清的4K甚至8K背景素材能大幅提升整体质感。本文将推荐4个提供顶级免费超清背景的网站…

作者头像 李华
网站建设 2026/4/9 6:05:39

法律文书朗读:帮助律师快速审阅大量文本内容

法律文书朗读&#xff1a;帮助律师快速审阅大量文本内容 在律师事务所的深夜办公室里&#xff0c;一位律师正逐字逐句地核对一份长达80页的并购合同。灯光下&#xff0c;他的眼睛已经有些干涩&#xff0c;注意力开始飘忽——这种场景在法律行业中再常见不过。面对动辄数百页的案…

作者头像 李华
网站建设 2026/4/12 11:05:33

技术直播预告撰写:邀请用户参与GLM-TTS互动演示

技术直播预告撰写&#xff1a;邀请用户参与GLM-TTS互动演示 在短视频、虚拟主播和AI陪伴应用爆发的今天&#xff0c;你是否曾为一段机械生硬的语音配音而皱眉&#xff1f;又是否想过&#xff0c;只需几秒钟录音&#xff0c;就能让AI“学会”你的声音&#xff0c;用你的语调讲出…

作者头像 李华