算法——基于C语言的基数排序

一、基数排序简介

基数排序是一种非比较排序算法,它将整数按照个位、十位、百位等位数进行排序。基数排序的主要思想是先按照最低位进行排序,然后依次按照高位进行排序,直到最高位,从而得到最终有序的序列。

基数排序的算法步骤如下:

  1. 将所有待比较数值统一为同样的位数,位数较小的数前面补零。
  2. 从最低位开始,依次进行一次计数排序(或桶排序),根据当前位数字进行分配。
  3. 重复以上步骤,直到最高位,最终得到有序序列。

基数排序的时间复杂度为O(d*(n+r)),其中d为最大位数,n为元素个数,r为基数(0-9为10进制时r为10)。

基数排序适用于位数较小、取值范围较小的整数排序,但对于位数较大的数字或负数排序则不太适用。

二、基数排序思想

基数排序是一种非比较性排序算法,其基本思想是将待排序的元素按照个位、十位、百位等基数进行排序。具体操作步骤如下:

  1. 将数组中的元素按照个位数字进行排序,可以使用计数排序等方法;
  2. 将数组按照个位数字排序后,根据十位数字再次排序;
  3. 以此类推,直到最高位数字排序完毕,整个数组就变成有序的了。

基数排序的时间复杂度取决于位数和元素的范围,适用于待排序元素范围不大的情况。其优点是稳定性高,不受待排序元素的大小影响,且不需要比较操作,适用于整数排序等场景。

三、代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<queue>

int Get_num_Max_digit(int arr[], int len)
{
	int max = arr[0];
	for (int i = 1; i < len; i++)
	{
		if (arr[i] > max)
		{
			arr[i] = max;
		}
	}
	//定义一个计数器,用于获取数组中最大值的位数
	int count = 0;
	while (max != 0)
	{
		max /= 10;
		count++;
	}
	return count;
}

//获取数字对应位数的值
int Get_num_corresponding_Bucket(int num, int gap)
{
	for (int i = 0; i < gap; i++)
	{
		num /= 10;
	}
	return num % 10;
}

//对数组进行一次基数排序
void Radix(int arr[], int len, int gap)
{
	std::queue<int> Bucket[10];//10个队列
	//遍历数组,将元素分配到对应的桶
	for (int i = 0; i < len; i++)
	{
		//Get_num_corresponding_Bucket(arr[i], gap) 的作用是:
		//提取 arr[i] 的第 gap 位数字(如 gap = 1 取个位,gap = 10 取十位)。
		int index = Get_num_corresponding_Bucket(arr[i], gap);
		Bucket[index].push(arr[i]);
	}
	
	int k = 0;
	for (int i = 0; i < 10; i++)
	{
		while (!Bucket[i].empty())//判断队列不空
		{
			arr[k++] = Bucket[i].front();//按桶顺序(0~9)收集元素,放回原数组
			Bucket[i].pop();//再将元素踢出来
		}
	}
}

//基数排序主函数
void Radix_Sort(int arr[], int len)
{
	int digit = Get_num_Max_digit(arr, len);
	for (int i = 0; i < digit; i++)
	{
		Radix(arr, len, i);
	}
}

void Show(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 170, 45, 75, 90, 802, 24, 2, 66 };
	int len = sizeof(arr) / sizeof(arr[0]);
	Radix_Sort(arr, len);
	Show(arr, len);
	return 0;
}

四、性能分析

4.1 时间复杂度

基数排序的时间复杂度为 O(d(n + r)),其中 d是数字的位数,n 是待排序元素的数量,r 是基数,通常为 10(十进制)。在最好情况下,当待排序元素的位数较少且分布较为均匀时,基数排序的时间复杂度接近 O(n)。这是因为在每一轮对特定位数进行排序时,分配和收集操作的时间复杂度与元素数量和基数有关,而如果位数较少且分布均匀,那么总的时间复杂度就会较低。

4.2 空间复杂度

  基数排序的空间复杂度为 O(n + r)。其中, n 是待排序元素的数量,r 是基数。空间复杂度主要来源于存储桶或计数数组的空间。在基数排序过程中,需要创建多个桶或计数数组来存储中间结果。例如,在十进制基数排序中,需要创建 个桶来存储不同位数的数字。每个桶的大小取决于待排序元素的数量,因此总的空间复杂度为 O(n + r)。

4.3 稳定性分析

基数排序是一种稳定的排序算法。稳定性是指在排序过程中,相等元素的相对顺序不会改变。基数排序之所以是稳定的,是因为在每一轮对特定位数进行排序时,采用的是稳定的计数排序或桶排序方法。例如,在对个位数字进行排序时,如果有多个数字的个位数字相同,那么它们在桶中的顺序与在原数组中的顺序是一致的。在后续的十位、百位等位数的排序过程中,也会保持这种相对顺序不变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值