八大排序算法 - 基数排序

一、算法简介

基数排序属于非比较型排序 ,依靠分配与收集思想完成排序,不依靠元素大小比较。原理:将整数按个位、十位、百位 依次排序,从低位到高位逐轮稳定排序,最终实现整体有序,常用 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. 笔试面试手写稳定排序优先选择基数排序
相关推荐
老四啊laosi1 小时前
[滑动窗口] 12. 将 x 减到 0 的最小操作数
算法·leetcode·将 x 减到 0 的最小操作数
一条大祥脚1 小时前
Codeforces Round 1098 (Div. 2)
算法·深度优先
时空自由民.1 小时前
平衡车PID控制系统(豆包版本)
算法
sno_guo2 小时前
直播抠图技术100谈之25---调色中曲线是最优解
人工智能·算法·机器学习·直播·内容运营·obs抠图·直播技术
故事和你912 小时前
洛谷-【图论2-2】最短路1
开发语言·数据结构·c++·算法·动态规划·图论
Simple-Soft2 小时前
指针的高级应用与技巧 - C语言的灵魂
c语言·数据结构·算法
南宫萧幕2 小时前
Simulink 从零搭建 HEV ECMS 环境:模块解析、排坑指南与智能算法接口预留
人工智能·算法·matlab·汽车·控制
子豪-中国机器人2 小时前
词云与条形码答案
算法
闲人编程2 小时前
Agent的评估体系(AgentEval):如何判断一个Agent好坏?
大数据·人工智能·python·算法·agent·智能体·swe