【数据结构】基数排序高位优先(MSDF)

基数排序常用写法是低位优先(LSD),在网上有很多,还有一种写法是高位优先排序(MSDF)

高位优先资料比较少,而且老师布置了一个高位优先的题目,所以也尝试了高位优先的写法,下面来说说吧,程序可以实现功能,但未必完美,期待大佬给出改进的建议🥰

高位优先基数排序的基本思路

  1. 确定基数:基数排序通常使用基数为 10,因为十进制数字的范围是从 0 到 9。
  2. 逐位排序:从最高位开始逐位进行排序,直到最低位。
  3. 使用桶排序:每一轮排序都使用桶排序(bucket sort)的思想,将数字按照当前位的值放入对应的桶中。
  4. 递归排序:对于每个桶中的元素,继续递归地进行基数排序。

图解算法

基数排序高位优先的思想是递归+分治

①确定最大值:8788,有4位,因为是高位优先,可以通过这样确定先比较千位上的数

②遍历数组,将每个数字放入对应其千位的数字的桶中

③第一趟排序之后, 在千位上已经有序了,遍历每个桶,如果这个桶中有数字,而且只有一个数字(只有一个数字时认为就是有序的),那么可以收集它了,0389,2375。

④收集到3号桶时,我们发现有好几个千位是3的,而且并不是有序的,那么这个桶还要继续排序,千位相同,那就比较百位,它的策略跟第一趟排序相同,这里就用到了递归

⑤第二趟排序之后,3号桶中的数字变得有序了,按照0~9遍历第二趟排序的桶,收集数字,那么第一层函数中的3号桶中的数字收集完毕,递归结束。

⑥继续遍历,第一层函数中的4号桶中不止一个元素,需要排序

⑦遍历递归后的桶中元素,并收集,发现8号桶中不止一个元素,对它进行递归

⑧4873,4871仍然未排好序,继续递归

经历这次递归,4873,4871已经有序,收集号元素后返回上一层递归,上一层递归继续返回,直到返回第一层函数中

递归的结束条件:

如果桶中只有一个元素,可以认为有序,递归结束,或者,已经比较完所有位数,即千位,百位,十位,个位都比较完,递归也结束

Code

主函数

cpp 复制代码
int main()
{

    vector<int>a={4873,4871,6248,2375,3320,5523,3246,8788,389,4573,389};
    int max_num=a[0];
    for(int i=1;i<a.size();i++)
    {
        max_num=max_num>a[i]?max_num:a[i];//找到最大值,知道有多少位
    }
    int num=to_string(max_num).size();//获取最大值的位数
    Radix_Sort_rec(a,int(pow(10,num)));//递归基数排序

    for(int i=0;i<temp.size();i++)cout<<temp[i]<<' ';//输出排序后的数组
    cout<<endl;
    return 0;
}

基数排序

cpp 复制代码
void Radix_Sort_rec(vector<int>a,int n)
{
    vector<vector<int>>bulb(10);//初始化10个桶,用来装数字(0~9)
    for(int i=0;i<a.size();i++)
    {
        bulb[a[i]/n%10].push_back(a[i]);//将对应位数的数字放入对应桶中
    }
    for(int i=0;i<10;i++)
    {
        if(bulb[i].size()){
            if(bulb[i].size()==1||n<10)Merge(bulb[i]);//递归结束,收集元素
            else Radix_Sort_rec(bulb[i],n/10);
        }
    }
}

收集元素

cpp 复制代码
vector<int>temp;
void Merge(vector<int>num)
{
    for(int i=0;i<num.size();i++)temp.push_back(num[i]);
}

完整代码

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;
/*
 实现MSDF(高位优先)算法给正整数排序
 注:正整数的输入可以设置诸如以下二维数组这种形式(也可自己根据自己的习惯自由设定):
 int A[NUM][RADIX] = {{4,8,7,3},{4,8,7,1},{6,2,4,8},{2,3,7,5},{3,3,2,0},{5,5,2,3},{3,2,4,6},
 {8,7,8,8},{0,3,8,9},{4,5,7,3}};//对4873、4871、6248等整数进行排序
 */
vector<int>temp;
void Merge(vector<int>num)
{
    for(int i=0;i<num.size();i++)temp.push_back(num[i]);
}
void Radix_Sort_rec(vector<int>a,int n)
{
    vector<vector<int>>bulb(10);//初始化10个桶,用来装数字(0~9)
    for(int i=0;i<a.size();i++)
    {
        bulb[a[i]/n%10].push_back(a[i]);//将对应位数的数字放入对应桶中
    }
    for(int i=0;i<10;i++)
    {
        if(bulb[i].size()){
            if(bulb[i].size()==1||n<10)Merge(bulb[i]);//递归结束,收集元素
            else Radix_Sort_rec(bulb[i],n/10);
        }
    }
}
int main()
{

    vector<int>a={4873,4871,6248,2375,3320,5523,3246,8788,389,4573,389};
    int max_num=a[0];
    for(int i=1;i<a.size();i++)
    {
        max_num=max_num>a[i]?max_num:a[i];//找到最大值,知道有多少位
    }
    int num=to_string(max_num).size();//获取最大值的位数
    Radix_Sort_rec(a,int(pow(10,num)));//递归基数排序

    for(int i=0;i<temp.size();i++)cout<<temp[i]<<' ';//输出排序后的数组
    cout<<endl;
    return 0;
}
相关推荐
侯小啾1 小时前
【03】C语言 强制类型转换 与 进制转换
c语言·数据结构·算法
AA陈超2 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-14 属性菜单 - 文本值行
c++·游戏·ue5·游戏引擎·虚幻
云知谷2 小时前
【经典书籍】C++ Primer 第15章类虚函数与多态 “友元、异常和其他高级特性” 精华讲解
c语言·开发语言·c++·软件工程·团队开发
weixin_582985183 小时前
OpenCV cv::Mat.type() 以及类型数据转换
c++·opencv·计算机视觉
oioihoii6 小时前
深入理解 C++ 现代类型推导:从 auto 到 decltype 与完美转发
java·开发语言·c++
报错小能手6 小时前
项目——基于C/S架构的预约系统平台 (1)
开发语言·c++·笔记·学习·架构
lingran__6 小时前
算法沉淀第十天(牛客2025秋季算法编程训练联赛2-基础组 和 奇怪的电梯)
c++·算法
一二学长7 小时前
快速排序(JAVA详细讲解快速排序的四种方式)
数据结构
大数据张老师7 小时前
数据结构——红黑树
数据结构·算法·红黑树
文火冰糖的硅基工坊8 小时前
[人工智能-大模型-54]:模型层技术 - 数据结构+算法 = 程序
数据结构·人工智能·算法