基数排序(C语言)

基数排序

基数排序(Radix sort)是一种非比较型的排序算法,最早用于解决卡片排序的问题。

它的工作原理是将待排序的元素拆分为k个关键字,其中k为最大值的位数,从低位开始进行稳定排序。(注意:数列中的元素都是非负整数)

基数排序是一种稳定的排序算法。

代码实现:

#include 
#include 
#include 

typedef unsigned long long ULL;

//数据预处理,保证每个元素的值都大于等于0(如果已知数列全是非负数就不必进行此处理了) 
int Pretreatment(int* nums, ULL* tmp, int numsSize){
	int bias = 0;
	for(int i = 0; i < numsSize; i++){
		if(nums[i] < bias){
			bias = nums[i];
			}
		}
	for(int i = 0; i < numsSize; i++){
		tmp[i] = nums[i] - bias;
		}
	return bias;
}

//基数排序

//LSD(最低位优先法)适用于位数较小的数列 
void LSDRadixSort(int* nums, int numsSize){
	ULL* tmp = (ULL*)calloc(numsSize, sizeof(ULL));
	int bias = Pretreatment(nums, tmp, numsSize);
	ULL buf[numsSize];
	ULL exp = 1;
	ULL maxval = 0;
	//找到最大值作为循环停止的标准 
	for(int i = 0; i < numsSize; i++){
		if(tmp[i] > maxval){
			maxval = tmp[i];
			}
		}
	//从低位到高位分配 
	while(maxval >= exp){
		int cnt[10];
		memset(cnt, 0, sizeof(cnt));
		for(int i = 0; i < numsSize; i++){
			int digit = (tmp[i] / exp) % 10;
			cnt[digit]++;
			}
		for(int i = 1; i < 10; i++){
			cnt[i] += cnt[i - 1];
			}
		for(int i = numsSize - 1; i >= 0; i--){
			int digit = (tmp[i] / exp) % 10;
			buf[--cnt[digit]] = tmp[i];
			}
		memcpy(tmp, buf, sizeof(ULL) * numsSize);
		exp = exp * 10;
		}
	for(int i = 0; i < numsSize; i++){
		nums[i] = tmp[i] + bias;
		}
	free(tmp);	 
}

int main(void) {
    int numsSize;
    scanf("%d", &numsSize);
	int* nums = (int*)calloc(numsSize, sizeof(int));
	for(int i = 0; i < numsSize; i++){
		scanf("%d", &nums[i]);
		}
	LSDRadixSort(nums, numsSize);
	for(int i = 0; i < numsSize; i++){
	    printf("%d", nums[i]);
	    if(i != numsSize - 1) printf(" ");
	    else printf("\n");
	    }
	return 0;
}

你可能感兴趣的:(排序,c语言,排序算法,算法)