当前位置: 首页 > news >正文

基数排序(Radix Sort)算法简介

【基数排序算法简介】
● 基数排序(Radix Sort)是一种‌非比较型整数排序算法‌,通过逐位分配和收集元素实现排序‌。
基数排序仅适用于整数或可转换为数字的字符串‌的排序。其核心原理是将整数按位数切割,从最低位(LSD)或最高位(MSD)开始依次排序,利用桶排序或计数排序作为子过程‌。基数排序是倍增法实现后缀数组(Suffix Array)的核心排序工具,其高效的 O(n) 时间复杂度直接决定了后缀数组整体算法的时间复杂度‌。

● 基数排序的步骤
(一)预处理阶段‌:计算数组中元素的最大位数,确定基数排序的轮数。

int maxbit(int n,int a[]) {int imax=0;for(int i=1; i<=n; i++) {int cnt=0, t=a[i];while(t!=0) {t=t/10;cnt++;}imax=max(imax,cnt);}return imax;
}

(二)按位排序阶段‌(从最低位到最高位)
(1)统计频次‌:遍历数组 a[],统计当前轮按位排序时当前位上每个数字(0-9)的出现次数,存储于频次数组 freq[] 中。

for(int i=0; i<=9; i++) freq[i]=0;
for(int i=1; i<=n; i++) {int x=(a[i]/div)%10;freq[x]++;
}

(2)计算前缀和:对频次数组 freq[] 做前缀和 freq[i]+=freq[i-1],i∈[1,9]。其中,freq[0] 的值为上步所得。此时,若有 freq[i]=x,则表示在按位排序的当前轮执行后,数组 a[] 中的各元素在当前位小于等于 i 的数有 x 个在基数排序中,计算前缀和的主要目的是‌为了快速确定数组 a[] 的元素在按位排序的当前轮执行后,它们在所得的有序序列中的位次

for(int i=1; i<=9; i++) {freq[i]+=freq[i-1];
}

(3)分配位次:逆序遍历数组 a[],依据元素 a[i] 的当前轮当前位元素的频次,将元素 a[i] 放入临时数组 rk[] 的对应位置。逆序遍历数组 a[],是为了‌保持基数排序的稳定性‌。为了应对数组 a[] 中,多个元素在按位排序的当前轮的当前位均为相同的 t,则需在给一个 t 安置后,执行 freq[t]--,为下一个相同的 t 预留正确的位次。

for(int i=n; i>=1; i--) {int t=(a[i]/div)%10;rk[freq[t]]=a[i];freq[t]--;
}

(4)更新数组‌:将当前轮按位排序结果 rk[] 覆盖原数组 a[],为下轮排序做准备。

for(int i=1; i<=n; i++) {a[i]=rk[i];
}


【基数排序算法实例】
假设我们有一个待排序的数组:a=[712, 303, 4, 18, 89, 999, 70, 26]。
在预处理阶段‌,通过计算可得数组 a[] 中元素的最大位数为 3,也即基数排序的轮数。
下面各步骤,以基数排序的第一轮,也即以数组 a[] 中各元素按位排序时的个位为例,进行算法陈述。

步骤1:统计频次‌
首先创建一个频次数组 freq(长度为 10,对应数字 0~9),统计数字 0~9 出现的次数。显然,对于给定的数组 a=[712, 303, 4, 18, 89, 999, 70, 26],其频率数组 freq=[1, 0, 1, 1, 1, 0, 1, 0, 1, 2]。这个频率数组在基数排序的下一步中会转换为前缀和数组,快速确定数组 a[] 的元素在按位排序的当前轮执行后,它们在所得的有序序列中的位次,目的是实现稳定排序。

步骤2:计算前缀和‌
执行
for(int i=1; i<=9; i++) freq[i]+=freq[i-1]; 后,频次数组 freq 的值变为 [1, 1, 2, 3, 4, 4, 5, 5, 6, 8]。此时,频次数组 freq 的语义更新为前缀和数组 freq,其含义如下所示。
freq[0] = 1:表示所有小于等于 0 的数字有 1 个
freq[1] = 1:表示所有小于等于 1 的数字有 1 个
freq[2] = 2:表示所有小于等于 2 的数字有 2 个
freq[3] = 3:表示所有小于等于 3 的数字有 3 个
……
freq[8] = 6:表示所有小于等于 8 的数字有 6 个
freq[9] = 8:表示所有小于等于 9 的数字有 8 个

步骤3:分配位次

逆序遍历数组 a[],依据元素 a[i] 的当前轮当前位元素的频次,将元素 a[i] 放入临时数组 rk[] 的对应位置。
i=8:a[8]=26 → t=(26/1)%10=6 → rk[freq[6]]=rk[5]=26 → freq[6]减为4
i=7:a[7]=70 → t=(70/1)%10=0 → rk[freq[0]]=rk[1]=70 → freq[0]减为0
i=6:a[6]=999 → t=(999/1)%10=9 → rk[freq[9]]=rk[8]=999 → freq[9]减为7
i=5:a[5]=89 → t=(89/1)%10=9 → rk[freq[9]]=rk[7]=89 → freq[9]减为6
i=4:a[4]=18 → t=(18/1)%10=8 → rk[freq[8]]=rk[6]=18 → freq[8]减为5
i=3:a[3]=4 → t=(4/1)%10=4 → rk[freq[4]]=rk[4]=4 → freq[4]减为3
i=2:a[2]=303 → t=(303/1)%10=3 → rk[freq[3]]=rk[3]=303 → freq[3]减为2
i=1:a[1]=712 → t=(712/1)%10=2 → rk[freq[2]]=rk[2]=712 → freq[2]减为1

步骤4:更新数组‌
将当前轮按位排序结果 rk[]
覆盖原数组 a[],为下轮排序做准备。
此时 a[1]~a[8] 的值为 rk[1]~rk[8] 的值:70, 712, 303, 4, 26, 18, 89, 999。
显然,70, 712, 303, 4, 26, 18, 89, 999 是按个位从小到大排序后的结果,之后将以此数据为基础进行下一轮(十位)的按位排序。


【算法代码:
基数排序求解洛谷P1177的代码

#include <bits/stdc++.h>
using namespace std;const int maxn=1e5+5;
int a[maxn];
int rk[maxn],freq[maxn];int maxbit(int n,int a[]) {int imax=0;for(int i=1; i<=n; i++) {int cnt=0, t=a[i];while(t!=0) {t=t/10;cnt++;}imax=max(imax,cnt);}return imax;
}void Radix_Sort(int n,int a[]) {int cnt=maxbit(n,a);int div=1;while(cnt--) {for(int i=0; i<=9; i++) {freq[i]=0;}for(int i=1; i<=n; i++) {int t=(a[i]/div)%10;freq[t]++;}for(int i=1; i<=9; i++) {freq[i]+=freq[i-1];}for(int i=n; i>=1; i--) {int t=(a[i]/div)%10;rk[freq[t]]=a[i];freq[t]--;}for(int i=1; i<=n; i++) {a[i]=rk[i];}div=div*10;}
}int main() {int n;cin>>n;for(int i=1; i<=n; i++) {cin>>a[i];}Radix_Sort(n,a);for(int i=1; i<=n; i++) {cout<<a[i]<<" ";}return 0;
}/*
in:
5
12345 12 123 1 12out:
1 12 12 123 12345
*/




【参考文献】
https://www.cnblogs.com/pdpdzaa/p/17522307.html
https://www.cnblogs.com/pdpdzaa/p/17532682.html
https://zhuanlan.zhihu.com/p/655379377
https://www.cnblogs.com/000zwx000/p/12330710.html


 

http://www.dtcms.com/a/535816.html

相关文章:

  • 【C++项目】基于设计模式的同步异步日志系统(前置基础知识)
  • JDK8时间相关类,时间对象都是不可变的
  • Java内存模型(JMM)与JVM内存模型
  • h5响应式网站模板如何做公司自己的网站首页
  • CentOS7 使用 centos-release-scl-rh yum库安装 devtoolset
  • UI自动化测试:Jenkins配置
  • 软件开发公司网站模板网站开发工程师绩效
  • c++中list详解
  • 杨凌美畅用 TDengine 时序数据库,支撑 500 条产线 2 年历史数据追溯
  • 4.Rocky Linux 网络配置
  • <数据集>yolo螺丝螺母识别数据集<目标检测>
  • Visual Studio 2022 安装使用:Entity Framework Core
  • Oracle 19c 备份技术教学文档
  • 企业做网站电话约见客户的对话wordpress 创意
  • 网站引导制作做网站公司 包含了服务器费用吗
  • 【SpringCloud】Hystrix、Resilience4j 简述
  • npm 发布node后台安装包和依赖库的方法
  • HarmonyOS语音交互与媒体会话开发实战
  • 【LeetCode】89. 格雷编码
  • 20251027在Ubuntu20.04.6上编译AIO-3576Q38开发板的Buildroot系统解决qt5webengine编译异常的问题
  • 【Linux】文件归属与迁移:chown修改拥有者、chgrp调整所属组,解决团队协作中的权限交接问题
  • 等离激元光催化:从实验室突破到碳中和战场的技术革命
  • 2025年6月全国大学英语四级真题试卷、听力音频及答案解析PDF电子版(三套全)
  • CAS:1628029-06-0,UV-Tracer-炔-琥珀酰亚胺酯,光学特性
  • 中国建设银行网站怎么登录不上去湖北黄石域名注册网站建设
  • 制作网站心得如何建微信公众号平台
  • Redis黑马点评 分布式锁
  • Lua-function的常见表现形式
  • 免费com域名网站提升wordpress性能的插件
  • 面试150——堆