基数排序与其他的排序方法(http://blog.csdn.net/laojiu_/article/details/50813637)都不同,它不需要比较关键字的大小。
算法的时间复杂度是O(n). 相比于快速排序的O(nlgn),从表面上看具有不小的优势.但事实上可能有些出入,因为基数排序的n可能具有比较大的系数K.因此在具体的应用中,应首先对这个排序函数的效率进行评估.
不妨通过一个具体的实例来展示一下,基数排序是如何进行的。
设有一个初始序列为: R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100}。
我们知道,任何一个阿拉伯数,它的各个位数上的基数都是以0~9来表示的。
所以我们不妨把0~9视为10个桶。
我们先根据序列的个位数的数字来进行分类,将其分到指定的桶中。例如:R[0] = 50,个位数上是0,将这个数存入编号为0的桶中。
分类后,我们在从各个桶中,将这些数按照从编号0到编号9的顺序依次将所有数取出来。
这时,得到的序列就是个位数上呈递增趋势的序列。
按照个位数排序: {50, 30, 0, 100, 11, 2, 123, 543, 187, 49}。
接下来,可以对十位数、百位数也按照这种方法进行排序,最后就能得到排序完成的序列。
代码实现:
#include<iostream>
using namespace std;
/* 获取x这个数的d位数上的数字,比如获取123的1位数,结果返回3 */
int GetDigit(int x,int d)
{
int a[] = { 1, 1, 10, 100 }; //本实例中的最大数是百位数,所以只要到100就可以了
return (x / a[d]) % 10;
}
/* 参数含义分别为:待排序数组;待排序数组首元素下标;待排序数组末元素下标;数组元素最大的位数,此处假设最大是百位数(3位数) */
void RadixSort(int arry[], int begin, int end, int digitLen)
{
int radix = 10; // 基数
int i = 0, j = 0;
int *count = new int[radix]; // 存放各个桶的数据统计个数
int *assit = new int[end - begin + 1];
// 按照从低位到高位的顺序执行排序过程
for (int d = 1; d <= digitLen; d++)
{
// 置空各个桶的数据统计
for (i = 0; i < radix; i++)
count[i] = 0;
// 统计各个桶将要装入的数据个数
for (i = begin; i <= end; i++)
{
j = GetDigit(arry[i], d);
count[j]++;
}
// count[i]表示第i个桶的右边界索引
for (i = 1; i < radix; i++)
count[i] = count[i] + count[i - 1];
// 将数据依次装入桶中
// 这里要从右向左扫描,保证排序稳定性
for (i = end; i >= begin; i--)
{
j = GetDigit(arry[i], d); // 求出关键码的第k位的数字, 例如:576的第3位是5
assit[count[j] - 1] = arry[i]; //放入对应的桶中,count[j]-1是第j个桶的右边界索引
count[j]--; // 对应桶的装入数据索引减一
}
// 将已分配好的桶中数据再倒出来,此时已是对应当前位数有序的表
for (i = begin, j = 0; i <= end; i++, j++)
arry[i] = assit[j];
}
delete[]count;
delete[]assit;
}
int main()
{
int arry[] = { 50, 123, 543, 187, 49, 30, 0, 2, 11, 100 };
int len = sizeof(arry) / sizeof(int);
RadixSort(arry, 0, len - 1, 3);
for (int i = 0; i < len; i++)
cout << arry[i] << " ";
cout << endl;
return 0;
}
返回目录---->数据结构与算法目录
参考链接: http://www.cnblogs.com/jingmoxukong/p/4311237.html