首页 > 编程语言 >算法与数据结构——基数排序

算法与数据结构——基数排序

时间:2024-11-05 17:12:42浏览次数:2  
标签:数据结构 nums int 计数 算法 基数排序 exp 排序

基数排序

基数排序(radix sort)的核心思想与计数排序一致,也通过统计个数来实现排序。计数排序适用于数据量n较大但数据范围m比较小的情况。假设我们需要对n=106个学号进行排序,而学号是一个8位数字,这意味着数据范围m=108非常大,使用计数排序需要分配大量内存空间,而基数排序可以避免这种情况。

基数排序在计数排序的基础上,利用数字各位之间的递进关系,依次对每一位进行排序,从而得到最终的排序结果。

算法流程

以学号数据为例,假设数字的最低位是第1位,最高位是第8位。算法流程如下:

  1. 初始化位数k = 1。
  2. 对学号的第k位执行“计数排序”。完成后,数据根据第k位从小到大排序。
  3. 将k增加1, 然后返回步骤2.继续迭代,直到所有位都排序完成后结束。

下面剖析代码实现。对于一个d进制的数字x,哟啊获取其第k位xk,可以使用以下计算公式:

其中 ⌊a⌋ 表示对浮点数a向下取整,而 mod d表示对d取模(取余)。对于学号数据,d=10且k ∈ [1, 8]。

此外,我们需要小幅度改动计数排序代码,是之可以根据数字的第k位进行排序:

/* 获取元素num的第k位 其中 exp = 10^(k - 1) */
int digit(int num, int exp){
	// 传入exp而非k 可以避免在此重复执行昂贵的次方运算
	return (num / exp) % 10;
}
/* 计数排序(根据num的第k位进行排序) */
void countingSortDigit(vector<int> &nums, int exp){
	// 10进制的位范围是0~9,因此需要长度为10的桶数组
	vector<int> counter(10, 0);
	int n = nums.size();
	// 统计0~9各数字的出现次数
	for (int i = 0; i < n; ++i){
		int d = digit(nums[i], exp);		// 获取nums[i]的第k位,记为d
		counter[d]++;						// 统计数字d的出现次数
	}
	// 求前缀和,将“出现个数”转换为“数组索引”
	for (int i = 1; i < 10; ++i){
		counter[i] += counter[i - 1];
	}
	// 倒序遍历,根据桶内统计结果,将各元素填入res
	vector<int> res(n, 0);
	for (int i = n - 1; i >= 0; --i){
		int d = digit(nums[i], exp);
		int j = counter[d] - 1;		// 获取d在数组中的索引 j
		res[j] = nums[i];					// 将当前元素填入索引 j
		counter[d]--;						// 将d的数量减1
	}
	// 使用结果覆盖原数组
	for (int i = 0; i < n; ++i){
		nums[i] = res[i];
	}
}
/* 基数排序 */
void radixSort(vector<int> &nums){
	// 获取数组最大元素,用于判断最大位数
	int m = *max_element(nums.begin(), nums.end());
	// 按照从低位到高位的顺序遍历
	for (int exp = 1; exp < m; exp *= 10){
		countingSortDigit(nums, exp);
	}
}

为什么从最低位开始排序?
在连续的排序轮次中,后一轮排序会覆盖前一轮排序的结果。举例来说,如果第一轮排序结果a < b,而第二轮排序结果a > b,那么第二轮的结果将取代第一轮的结果。由于数字的高位优先级高于低位,因此应该先排序低位再排序高位。

算法特性

相较于计数排序,基数排序适用于数值范围比较大的情况,但前提是数字必须是可以表示为固定位数的格式,且位数不能过大。例如,浮点数不适合使用基数排序,因为其位数k过大,可能导致时间复杂度O(nk)≫O(n2)。

  • 时间复杂度O(nk):设数据量为n、数据为d进制、最大位数为k,则对某一位执行计数排序使用O(n+d)时间,排序所有k位使用O((n+d)k)时间。通常情况下,d和k都相对较小,时间复杂度趋向O(n)。
  • 空间复杂度O(n+d)、非原地排序:与计数排序相同,基数排序需要借助长度为n和d的数组rescounter
  • 稳定排序:当计数排序稳定时,基数排序也稳定;当计数排序不稳定时,基数排序无法保证得到正确的排序结果。

标签:数据结构,nums,int,计数,算法,基数排序,exp,排序
From: https://www.cnblogs.com/1873cy/p/18515733

相关文章

  • 计算机毕业设计Python+大模型新能源汽车销量预测 汽车销量分析可视化 汽车爬虫 深度学
    温馨提示:文末有CSDN平台官方提供的学长联系方式的名片!温馨提示:文末有CSDN平台官方提供的学长联系方式的名片!温馨提示:文末有CSDN平台官方提供的学长联系方式的名片!作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO......
  • 【初阶数据结构篇】链式结构二叉树(续)
    文章目录须知......
  • 转 数据结构LMS-TREE 解析
    ##sample1LMS-TREE用于oceanbase数据库的内核,与传统数据库存在很多不一致的地方包括写多份数据,支持快速写,对读支持不如传统数据库,因为特意转载如下文章https://blog.51cto.com/u_15127649/3727804 平衡二叉树、B树、B+树、B*树、LSM树简介 转载mob604756fec84d2018......
  • AI智能分析视频分析网关打手机检测算法:科技赋能的智能监控新时代
    智能手机的广泛使用在便利我们生活的同时,也带来了一些挑战,特别是在教育、企业、家庭监护和公共场合等环境中,不恰当的手机使用可能会扰乱秩序和活动。为了应对这一挑战,打手机检测视频分析网关应运而生,成为一种高效、智能化的监控解决方案。一、技术背景打手机检测视频分析网关主......
  • 智慧园区算法视频分析服务器烟雾识别监控系统常见的推荐配置参考指南
    在智慧园区的构建中,视频监控系统扮演着至关重要的角色,尤其是算法视频分析服务器在烟雾识别方面的应用,它能够极大地提升园区的安全监控能力。为了确保系统的有效运行和精准识别,合理的硬件配置是基础。以下是智慧园区算法视频分析服务器的推荐配置参考指南。1、处理器(CPU):视频分析......
  • 文心一言 VS 讯飞星火 VS chatgpt (384)-- 算法导论24.5 4题
    四、设G=(V,E)......
  • 八字排盘PHP算法实现源码_网页前端设计(包含十神、藏干、大运流年)
    一、算法概述八字排盘是根据个人的出生年、月、日、时(四个时间点)计算出天干地支,并形成八字(年柱、月柱、日柱、时柱)。此外,排盘还涉及十神(如正财、偏财等)、藏干(每个地支内藏的天干)、大运和流年等内容。这些元素共同构成了一个人的命理信息。二、输入信息用户需要提供以下信息:......
  • 数据结构,问题 G: 字符串匹配问题
    题目描述字符串中只含有括号(),[],<>,{},判断输入的字符串中括号是否匹配。如果括号有互相包含的形式,从内到外必须是<>,(),[],{},例如。输入:[()]输出:YES,而输入([]),([])都应该输出NO。输入文件的第一行为一个整数n(0<n<20),表示以下有多少个由括号组成的字符串。接下来的......
  • 算法设计2——数组元素循环右移
    问题描述:有一个数组a包含n(n>1)个整数元素,设计一个尽可能高效的算法将数组a中的后面k个元素循环右移(k<=n),其中n是数组长度,0<=k<=n。例如:a=(1,2,3,4,5),k=3,结果:a=(3,4,5,1,2)思路:理解问题:将数组 a中的最后 k个元素移动到数组的前面,同时保持剩余元素的顺序不变。解决问题......
  • 人脸检测之MTCNN算法网络结构
    MTCNN(Multi-taskCascadedConvolutionalNetworks)是一种用于人脸检测和关键点检测的深度学习模型,特别适合在复杂背景下识别出多尺度的人脸。它通过多任务学习来实现人脸检测和人脸关键点定位(如眼睛、鼻子、嘴巴的位置),实现高精度的人脸区域定位和关键点提取。MTCNN主要由三个......