基数排序算法

Posted 大彤小忆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基数排序算法相关的知识,希望对你有一定的参考价值。

  基数排序(Radix Sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,是桶排序的扩展。将要排序的元素分配至某些“桶”中,藉以达到排序的作用。基数排序法是属于稳定性的排序,其效率高于其它的稳定性排序法。

  基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

  基数排序的排序思路:先以个位数的大小来对数据进行排序,接着以十位数的大小来多数进行排序,接着以百位数的大小……排到最后,就是一组有序的元素了。其中在以某位数进行排序的时候,是用“桶”来排序的。由于某位数(个位/十位……)的大小范围为0-9,所以我们需要10个桶,然后把具有相同数值的数放进同一个桶里,之后再把桶里的数按照0号桶到9号桶的顺序取出来,这样一趟下来,按照某位数的排序就完成了。

  例如: 使用桶排序算法将数组{ 144,203,6,905,47,215,836,26,527,602,848 }进行升序排序。

在这里插入图片描述
  实现代码如下所示。

#include<iostream>
using namespace std;

int maxbit(int arr[], int len)  //求数组的最大位数
{
	int maxData = arr[0];              // 最大数
	// 先求出最大数,再求其位数
	for (int i = 1; i < len; i++)
	{
		if (maxData < arr[i])
			maxData = arr[i];
	}
	int d = 1;
	int p = 10;
	while (maxData >= p)
	{
		maxData /= 10;
		++d;
	}
	return d;
}

void RadixSort(int arr[], int len)  //基数排序
{
	int d = maxbit(arr, len);  //数组中最大值的位数
	int *tmp = new int[len];
	int *count = new int[10]; //计数器
	int radix = 1;
	for (int i = 1; i <= d; i++) //进行d次排序
	{
		for (int j = 0; j < 10; j++)
			count[j] = 0; //每次分配前清空计数器
		for (int j = 0; j < len; j++)
		{
			int k = (arr[j] / radix) % 10; //统计每个桶中的记录数
			count[k]++;
		}
		for (int j = 1; j < 10; j++)
			count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
		for (int j = len - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
		{
			int k = (arr[j] / radix) % 10;
			tmp[count[k] - 1] = arr[j];
			count[k]--;
		}
		for (int j = 0; j < len; j++) //将临时数组的内容复制到arr中
			arr[j] = tmp[j];
		radix = radix * 10;
}
	delete[]tmp;
	delete[]count;
}

int main()
{
	int a[] = { 144,203,6,905,47,215,836,26,527,602,848 };
	int len = sizeof(a) / sizeof(a[0]);

	cout << "排序前:" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << a[i] << "  ";
	}
	cout << endl;

	RadixSort(a, len);

	cout << "排序后:" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << a[i] << "  ";
	}
	cout << endl;

	system("pause");
	return 0;
}

排序前:
144 203 6 905 47 215 836 26 527 602 848
排序后:
6 26 47 144 203 215 527 602 836 848 905

  时间复杂度 O ( n × k ) O ( n \\times k ) O(n×k)

  空间复杂度: O ( n + k ) O ( n + k ) O(n+k)

  稳定性: 稳定。

  基数排序 vs 计数排序 vs 桶排序: 这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:
    ■ 基数排序:根据键值的每位数字来分配桶;
    ■ 计数排序:每个桶只存储单一键值;
    ■ 桶排序:每个桶存储一定范围的数值。

以上是关于基数排序算法的主要内容,如果未能解决你的问题,请参考以下文章

数据结构-排序之基数排序(使用java代码实现)

数据结构-排序之基数排序(使用java代码实现)

数据结构-排序之基数排序(使用java代码实现)

经典十大排序算法(含升序降序,基数排序含负数排序)Java版完整代码建议收藏系列

c中的基数排序算法[关闭]

数据结构之排序算法Java实现—— 基数排序法