八大排序算法 - 基数排序

一、算法简介

基数排序属于非比较型排序 ,依靠分配与收集思想完成排序,不依靠元素大小比较。原理:将整数按个位、十位、百位 依次排序,从低位到高位逐轮稳定排序,最终实现整体有序,常用 LSD 低位优先 方式。

时间复杂度:\(O(d(n+r))\) d 为最大位数,r 为基数

空间复杂度:\(O(n+r)\)

稳定性:稳定排序

适用场景:整数、手机号、日期等固定位数数据排序

二、排序思路

  1. 找出数组中最大值,确定最大数字位数,决定排序轮数
  2. 以 10 为基数,依次对个位、十位、百位进行排序
  3. 每一轮使用计数排序思想统计频次,完成一轮位次排序
  4. 逐位循环,全部位数排完即整体有序

三、C++ 完整实现代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 获取数组最大值
int getMax(vector<int>& arr)
{
    int maxVal = arr[0];
    for (int num : arr)
    {
        if (num > maxVal)
            maxVal = num;
    }
    return maxVal;
}

// 基数排序 LSD 低位优先
void radixSort(vector<int>& arr)
{
    if (arr.size() <= 1) return;

    int maxNum = getMax(arr);
    // exp 代表当前位数 1个位 10十位 100百位
    int exp = 1;

    while (maxNum / exp > 0)
    {
        vector<int> temp(arr.size());
        // 0~9计数桶
        vector<int> count(10, 0);

        // 1.统计当前位数字出现次数
        for (int i = 0; i < arr.size(); i++)
        {
            int digit = (arr[i] / exp) % 10;
            count[digit]++;
        }

        // 2.累加次数,确定元素位置
        for (int i = 1; i < 10; i++)
        {
            count[i] += count[i - 1];
        }

        // 3.倒序放入临时数组,保证排序稳定
        for (int i = arr.size() - 1; i >= 0; i--)
        {
            int digit = (arr[i] / exp) % 10;
            temp[count[digit] - 1] = arr[i];
            count[digit]--;
        }

        // 4.临时数组覆盖原数组
        arr = temp;
        // 进位处理下一位
        exp *= 10;
    }
}

// 打印数组
void printArr(vector<int>& arr)
{
    for (int val : arr)
    {
        cout << val << " ";
    }
    cout << endl;
}

int main()
{
    vector<int> nums = {53, 3, 542, 748, 14, 214, 154, 63, 616};
    cout << "排序前:";
    printArr(nums);

    radixSort(nums);

    cout << "排序后:";
    printArr(nums);
    return 0;
}

四、代码核心解析

  1. getMax 函数遍历数组拿到最大值,用来判断需要排序多少位数字。

  2. 逐位排序逻辑

  3. (arr[i]/exp)%10 取出当前位次数字

  4. count 数组统计 0-9 每个数字出现次数

  5. 倒序遍历赋值,保证稳定排序,不打乱前面低位排好的顺序

  6. 位数递进 exp *= 10 依次切换个位、十位、百位,直到所有位数排序完成。

五、优缺点总结

优点

  1. 线性排序效率高,数据量大时远超冒泡、插入排序
  2. 排序稳定,相同数值相对位置不变
  3. 逻辑简单,容易手写实现

缺点

  1. 仅适合整数类数据排序,使用场景受限
  2. 存在额外数组开销,占用内存
  3. 数字位数极大时,排序轮数变多,效率下降

六、使用场景

  1. 海量手机号、QQ 号、学号排序
  2. 统计类大数据整数排序
  3. 笔试面试手写稳定排序优先选择基数排序
相关推荐
aichitang20249 小时前
前端小skill
前端·人工智能·算法·ai·前端框架
All for pursuit.10 小时前
【链表-9】146.LRU缓存
数据结构·c++·算法·leetcode
木子算法10 小时前
测出来的值会抖:约束和目标带噪声时,「可行」和「更好」该怎么判
人工智能·算法·目标跟踪
hanlin0311 小时前
刷题笔记:力扣第144题-二叉树的前序遍历
笔记·算法·leetcode
金士曼11 小时前
从规则到涌现:算法认知的三个层次
算法
AgentMaster12 小时前
数据资产化落地难题:5款数据中台系统架构对比与实施记录
大数据·人工智能·算法
鹿角片ljp12 小时前
从 Kimi Cyber Reasoning 学习网络安全推理数据集:从 Reasoning SFT 到安全 Agent 数据设计
数据结构·算法
residual_fan13 小时前
航空发动机故障诊断专用智能体(三):基于对比学习的时序特征区分方法
人工智能·算法·数据挖掘·数据分析
高亦真14 小时前
今天是学习嵌入式的第39天
linux·学习·算法
Omics Pro14 小时前
AI药物研发10原则!欧盟EMA×美国FDA
数据库·人工智能·算法·机器学习·自然语言处理