排序【8】基数排序

基数排序是一种借助多关键字排序的思想对单逻辑关键字进行关系的方法。基数排序

不需要进行记录关键字间的比较。

时间复杂度:最好时间:O(kn)    最坏时间:O(kn)   平均时间:O(kn)   

空间复杂度:O(n);

基数排序是一种稳定的排序


主要有两个过程:

1、分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中,比如(54, 各位为4,则放入4号桶中)

2、收集,再将放置在0~9号桶中的数据按顺序放到数组中

我说到这,相信很多人都不太理解,那么我就详细说明一下,首先什么叫借助多个关键字排序,对于

整形序列而言,我们将这样的多关键字理解为 数位(个位, 十位,百位,千位、、、),也就是说通过数位

进行排序,那么是怎么通过数位进行排序的呢?

我们以 int a[] = {224, 23, 15,7, 18,90};  我们知道每个数位都是0~9,第一次按照个位的顺序进行排序,

按照自左向右, 自上而下的顺序将新的序列代替原来的序列,第二次我们按照十位的顺序进行排序,

第三次我们按照百位的顺序进行排序,因为序列中最大数也只有百位,所以排序排到这里就已经结束了


基数排序代码:

#include <stdio.h>
#include <stdlib.h>

void RadixCountSort(int *index, int *a, int len)
{
	int i;
	int *count = (int *)malloc(sizeof(int) * 10);
	int *sort = (int *)malloc(sizeof(int) * 10);

	for (i = 0; i < 10; i++)
	{
		count[i] = 0;              //负责清空桶
	}

	for (i = 0; i < len; i++)          //对应桶内存放的个数,对应的数位是几,就在对应的痛的位置加1
	{
		count[index[i]]++;
	}

	for (i = 1; i < 10; i++)
	{
		count[i] = count[i] + count[i-1];  //前面的个数 == 下标加1
	}

	for (i = len-1; i >= 0; i--)
	{
		count[index[i]]--;                  //计算下标,最终结果是  下标加1,所以要减去1才是真正的下标
		sort[count[index[i]]] = a[i];       //将原序列重新排序
	}

	for (i = 0; i < len; i++)
	{
		a[i] = sort[i];
	}

	free(sort);
	free(count);
}

void RadixSort(int *a, int len)
{
	int i,x = 1;
	int tmp = 1;
	int *radix = (int *)malloc(sizeof(int)*len);     //保存每一轮对应数位的值

	while (x)
	{
		tmp = tmp * 10;
		x = 0;

		for (i = 0; i < len; i++)
		{
			radix[i] = a[i] % tmp;            //例如:tmp = 100时, 求出个位和十位的数  142 % 100 = 42;
			radix[i] = radix[i] / (tmp / 10); //  42 / (100 / 10) = 4;
			if (a[i] / tmp > 0)
			{
				x = 1;                    //判断是否进行 下一轮  循环
			}

		}

		RadixCountSort(radix, a, len);            //每一轮求出  对应数位的值  之后再重新排序
	}

	free(radix);
}


int main()
{
	int i;
	int a[] = {5, 9, 0, 142, 32, 18, 6, 13, 56, 90};
	int length = sizeof(a) / sizeof(a[0]);

	RadixSort(a, length);

	for (i = 0; i < length; i++)
	{
		printf("%d ", a[i]);
	}

	printf("\n");

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值