八大排序算法 - 基数排序

一、算法简介

基数排序属于非比较型排序 ,依靠分配与收集思想完成排序,不依靠元素大小比较。原理:将整数按个位、十位、百位 依次排序,从低位到高位逐轮稳定排序,最终实现整体有序,常用 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. 笔试面试手写稳定排序优先选择基数排序
相关推荐
To_OC6 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC6 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK8 小时前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌20 小时前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局20 小时前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象20 小时前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法
统计实现局20 小时前
对称不定分解(Bunch-Kaufman):为什么 Cholesky 不够用
算法
统计实现局20 小时前
dqrsl 拆解:拿着 QR 结果能算出哪 5 种东西
算法
统计实现局20 小时前
为什么 Cholesky 求逆比 Gauss-Jordan 快一倍——行列式溢出防护详
算法