基数排序【C语言】

news/2025/2/21 2:55:17

基数排序(Radix Sort)是一种非比较排序算法,可以在O(nk)的时间复杂度内完成排序,其中n是待排序元素的数量,k是所有数字的最大位数。基数排序首先将数字按照位数进行分组,通常采用稳定的排序算法(如计数排序)来完成每个位的排序。

代码注释版: 

void radixSort(int *a, int num) {
    if (num <= 0) return; // 处理空数组

    // 1. 寻找最大值和最小值
    int max = a[0], min = a[0];
    for (int i = 1; i < num; i++) {
        if (a[i] > max) max = a[i];
        if (a[i] < min) min = a[i];
    }

    // 2. 处理负数偏移(存在溢出风险)
    long long offset = -(long long)min; // 转为long long防止溢出
    for (int i = 0; i < num; i++) {
        a[i] += offset; // 隐含风险:若原a[i] + offset超出int范围,实际会溢出
    }
    max += offset; // 更新最大值

    // 3. 基数排序主循环
    for (long long exp = 1; max / exp > 0; exp *= 10) { // 使用long long防止exp溢出
        int count[10] = {0};

        // 统计当前位分布
        for (int i = 0; i < num; i++) {
            count[(a[i] / exp) % 10]++;
        }

        // 计算累积分布
        for (int i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }

        // 动态分配临时数组(避免栈溢出)
        int *temp = (int *)malloc(num * sizeof(int));
        if (!temp) {
            perror("Memory allocation failed");
            exit(EXIT_FAILURE);
        }

        // 从后向前填充临时数组(保证稳定性)
        for (int i = num - 1; i >= 0; i--) {
            int digit = (a[i] / exp) % 10;
            temp[--count[digit]] = a[i];
        }

        // 写回原数组
        for (int i = 0; i < num; i++) {
            a[i] = temp[i];
        }

        free(temp); // 释放临时内存

        // 提前终止检测:避免exp溢出后死循环
        if (exp >= 1e10) break; 
    }

    // 4. 恢复原始值(同样注意溢出)
    for (int i = 0; i < num; i++) {
        a[i] -= offset;
    }
}

代码引用版(直接用):

int radixSort(int *a, int num) {
	int max = a[0], min = a[0];
	for (int i = 1; i < num; i++) {
		if (a[i] > max)max = a[i];
		if (a[i] < min)min = a[i];
	}
	for (int i = 0; i < num; i++) {
		a[i] += (-min);
	}
	max += (-min);
	for (int exp = 1; max / exp > 0; exp *= 10) {
		int count[10] = {0};
		for (int i = 0; i < num; i++) {
			count[(a[i] / exp) % 10]++;
		}
		for (int i = 1; i < 10; i++) {
			count[i] += count[i - 1];
		}
		int *temp = (int *)malloc(num * sizeof(int));
		for (int i = num - 1; i >= 0; i--) {
			int q = (a[i] / exp) % 10;
			temp[count[q] - 1] = a[i];
			count[q]--;
		}
		for (int i = 0; i < num; i++) {
			a[i] = temp[i];
		}
		free(temp);
		if (exp >= 1e10)return -1;
	}
	for (int i = 0; i < num; i++) {
		a[i] -= (-min);
	}
	return 0;
}


http://www.niftyadmin.cn/n/5857327.html

相关文章

三种安全协议 IPSec SSL PGP

IPSec、SSL和PGP是三种常见的安全协议&#xff0c;它们在不同的应用场景中被用来保障数据的保密性、完整性和身份验证。 1. IPSec (Internet Protocol Security) 功能&#xff1a;IPSec是一个用于在IP网络上实现安全通信的协议套件&#xff0c;主要用于保护IP数据包的传输。它…

基于SpringBoot+vue+uniapp的投票小程序+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

解锁机器学习核心算法 | 支持向量机:机器学习中的分类利刃

一、引言 在机器学习的庞大算法体系中&#xff0c;有十种算法被广泛认为是最具代表性和实用性的&#xff0c;它们犹如机器学习领域的 “十大神器”&#xff0c;各自发挥着独特的作用。这十大算法包括线性回归、逻辑回归、决策树、随机森林、K - 近邻算法、K - 平均算法、支持向…

【云安全】云原生- K8S 污点横移

什么是“污点横移”&#xff1f; 在 K8S 中&#xff0c;利用污点&#xff08;Taint&#xff09;进行横向移动渗透是指攻击者通过操纵或绕过集群中的污点和容忍&#xff08;Toleration&#xff09;机制&#xff0c;将恶意负载&#xff08;Pod&#xff09;调度到原本受保护的节点…

负载均衡 LVS vs Nginx 对比

Nginx特点 正向代理与反向代理负载均衡动静分离 Nginx的优势 可操作性大网络依赖小安装简单支持健康检查以及请求重发 LVS 的优势 抗负载能力强配置性低工作稳定无流量 &#xff08;Nginx是双向的&#xff0c;LVS并非完全单向&#xff09;LVS三种模式中,虽然DR模式以及TU…

【核心算法篇三】《DeepSeek强化学习:Atari游戏训练框架解析》

大家好,今天我们来聊聊一个非常酷的话题——DeepSeek强化学习框架,特别是它在Atari游戏训练中的应用。如果你对人工智能、机器学习或者游戏AI感兴趣,那么这篇文章绝对不容错过。我们会从基础概念讲起,逐步深入到DeepSeek的核心原理和实现细节,最后还会探讨一些实际应用中的…

002 SpringCloudAlibaba整合 - Feign远程调用、Loadbalancer负载均衡

前文地址&#xff1a; 001 SpringCloudAlibaba整合 - Nacos注册配置中心、Sentinel流控、Zipkin链路追踪、Admin监控 文章目录 8.Feign远程调用、loadbalancer负载均衡整合1.OpenFeign整合1.引入依赖2.启动类添加EnableFeignClients注解3.yml配置4.日志配置5.远程调用测试6.服务…

3.10 实战Hugging Face Transformers:从文本分类到模型部署全流程

实战Hugging Face Transformers:从文本分类到模型部署全流程 一、文本分类实战:IMDB电影评论情感分析 1.1 数据准备与预处理 from datasets import load_dataset from transformers import AutoTokenizer # 加载IMDB数据集 dataset = load_dataset("imdb") …