蓝桥301实现基数排序

原理

题目目标:通过基数排序算法对整数序列进行升序排列。
核心方法:从最低位到最高位依次进行稳定分桶排序,利用字符串处理方便按位操作。


步骤

  1. 转换与补零:将整数转为字符串,补前导零使等长。
  2. 逐位分桶:从最低位到最高位,每次按当前位数字分到0-9桶中。
  3. 合并桶:按桶顺序收集元素,保持稳定性。
  4. 输出结果:去除前导零后输出排序后的数字。

图示法表示步骤(样例输入 7 1 4 8 5 2

初始字符串​(补零后长度1):["7","1","4","8","5","2"]

  1. 第1轮(个位)排序
    • 分桶:0-9桶按个位数字分组。
    • 结果:["1","2","4","5","7","8"](已有序)。
      最终输出1 2 4 5 7 8

代码关键行注释

for (int digit_pos = maxlength - 1; digit_pos >= 0; digit_pos--)  
// 从最低位(字符串末位)向最高位依次处理  

buckets[current_digit].push_back(s);  
// 根据当前位数字将元素放入对应桶  

vec[i].substr(first_non_zero)  
// 输出去除前导零后的实际数值  

完整代码程序

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    vector<string> vec(n);
    int maxlength = 0;
    // 转换为字符串并计算最大长度
    for (int i = 0; i < n; i++) {
        vec[i] = to_string(nums[i]);
        maxlength = max(maxlength, (int)vec[i].size());
    }
    // 补前导零,使所有字符串等长
    for (int i = 0; i < n; i++) {
        if (vec[i].size() < maxlength) {
            vec[i] = string(maxlength - vec[i].size(), '0') + vec[i];
        }
    }
    // 基数排序:按每一位从低位到高位进行稳定排序
    for (int digit_pos = maxlength - 1; digit_pos >= 0; digit_pos--) {
        vector<vector<string>> buckets(10); // 0-9共10个桶
        // 将当前位的数字分入对应桶中
        for (const string& s : vec) {
            int current_digit = s[digit_pos] - '0';
            buckets[current_digit].push_back(s);
        }
        // 收集桶中的元素,保持稳定性
        vec.clear();
        for (int d = 0; d < 10; d++) {
            for (const string& s : buckets[d]) {
                vec.push_back(s);
            }
        }
    }
    // 输出去除前导零后的结果
    for (int i = 0; i < n; i++) {
        string s = vec[i];
        // 找到第一个非零字符的位置
        size_t first_non_zero = s.find_first_not_of('0');
        if (first_non_zero == string::npos) { // 全零情况
            cout << "0";
        } else {
            cout << s.substr(first_non_zero);
        }
        if (i != n - 1) cout << " ";
    }
    return 0;
}

时间复杂度

  • 时间复杂度:​O(k·n),其中 k 为最大位数,n 为元素个数。
  • 空间复杂度:​O(n + 10·k),用于存储分桶的临时空间。

总结

  1. 代码优势
    • 正确性:通过字符串处理简化了按位操作,稳定分桶确保排序正确。
    • 鲁棒性:处理全零情况和前导零的去除逻辑完善。
  2. 潜在限制
    • 仅限非负整数:未处理负数,但题目未要求。
    • 字符串转换开销:对极大整数可能影响性能,但符合题目约束。
  3. 适用场景
    • 整数位数差异较小的数据集。
    • 需要稳定排序且数值范围可控的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值