基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用 基数排序法是属于稳定性的排序,基数排序法是效率高的稳定性排序法。 基数排序(Radix Sort)是桶排序的扩展,它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。
下面举例说明:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
void radixSort(int arr[],int len)
{
//先求出数组中最大的数
int max = arr[0];
for (int i = 0; i < len; i++)
{
if (max < arr[i])
max = arr[i];
}
//计算最大的数是几位数
int maxlen = (int)(log10(max)) + 1;
//定义一个二维数组,表示十个桶,每个桶的就是一个数组
//未了防止数据溢出,每个桶的最大长度为len,即所有元素都放入一个桶中
int* bucket[10];
for (int i = 0; i < 10; i++)
{
bucket[i] = new int[len];
}
//定义一个一维数组来记录各个桶每一次放入数据的个数
int bucketNumCount[10] = { 0 };
//第一轮:针对每个元素的个位进行排序处理
for (int i = 0; i < len; i++)
{
//取出每个元素的个位进行处理
int digitOfElement = arr[i] / 1 % 10;
//放入到个位对应的桶中
bucket[digitOfElement][bucketNumCount[digitOfElement]] = arr[i];
//对应桶内个数加一
bucketNumCount[digitOfElement]++;
}
//按照一维数组下标,即桶的顺序,依此取出数据,放入原来的数组中
int index = 0;
//遍历每一个桶,将每一个桶中数据放入到原数组中
for (int i = 0; i < 10; i++)
{
//如果第i个桶中有元素就放,否则不放
if (bucketNumCount[i] != 0)
{
//将第i个桶中元素全部倒出来
for (int j = 0; j < bucketNumCount[i]; j++)
{
arr[index++] = bucket[i][j];
}
}
//最后因为当前桶内元素全部倒出,要置空
bucketNumCount[i] = 0;
}
//打印
cout << "个位排序后:" << endl;
for_each(arr, arr + 6, [](int val) {cout << val << " "; });
cout << endl;
//第二轮:针对每个元素的十位进行排序处理
for (int i = 0; i < len; i++)
{
//取出每个元素的十位进行排序处理
int digitOfElement = arr[i] / 10 % 10;
//放入到对应的桶中
bucket[digitOfElement][bucketNumCount[digitOfElement]] = arr[i];
//对应桶中的数量加一
bucketNumCount[digitOfElement]++;
}
//按照一维数组下标,即桶的顺序,依此取出数据,放入原来的数组中
index = 0;
//遍历每一个桶,将每一个桶中数据放入到原数组中
for (int i = 0; i < 10; i++)
{
//如果当前第i个桶中存在元素才倒出
if (bucketNumCount[i] != 0)
{
//第i个桶中存在元素,将桶中所有元素倒出来,挨个放入数组中
for (int j = 0; j < bucketNumCount[i]; j++)
{
arr[index++] = bucket[i][j];
}
}
//当前第i个桶倒完后,将桶内元素个数为0
bucketNumCount[i] = 0;
}
//打印
cout << "十位排序后:" << endl;
for_each(arr, arr + 6, [](int val) {cout << val << " "; });
cout << endl;
//第三轮:针对每个元素的百位进行排序处理
for (int i = 0; i < len; i++)
{
//取出数组中每个元素的百位放入对应桶内
int digitOfElement = arr[i] / 100 % 10;
bucket[digitOfElement][bucketNumCount[digitOfElement]] = arr[i];
//对应桶中元素个数加一
bucketNumCount[digitOfElement]++;
}
//按照一维数组下标,即桶的顺序,依此取出数据,放入原来的数组中
index = 0;
//将桶内的元素以此倒回数组
for (int i = 0; i < 10; i++)
{
if (bucketNumCount[i] != 0)
{
for (int j = 0; j < bucketNumCount[i]; j++)
{
arr[index++] = bucket[i][j];
}
}
bucketNumCount[i] = 0;
}
//打印
cout << "百位排序后:" << endl;
for_each(arr, arr + 6, [](int val) {cout << val << " "; });
cout << endl;
}
void test()
{
int arr[6] = { 53, 3, 542, 748, 14, 214 };
radixSort(arr, 6);
cout << "最终排序结果:" << endl;
for_each(arr, arr + 6, [](int val) {cout << val << " "; });
cout << endl;
}
int main()
{
test();
system("pause");
return 0;
}
上面这个例子中没有用到我们定义的maxlen这个变量,是因为为了给大家演示排序过程。 下面给出简化版本,即用上maxlen这个变量:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
void radixSort(int arr[],int len)
{
//先求出数组中最大的数
int max = arr[0];
for (int i = 0; i < len; i++)
{
if (max < arr[i])
max = arr[i];
}
//计算最大的数是几位数
int maxlen = (int)(log10(max)) + 1;
//定义一个二维数组,表示十个桶,每个桶的就是一个数组
//未了防止数据溢出,每个桶的最大长度为len,即所有元素都放入一个桶中
int* bucket[10];
for (int i = 0; i < 10; i++)
{
bucket[i] = new int[len];
}
//定义一个一维数组来记录各个桶每一次放入数据的个数
int bucketNumCount[10] = { 0 };
//最外层for循环负责对每一位数字都进行一次归桶排序拿出操作
for (int i = 0,n=1; i < maxlen; i++,n*=10)
{
//对当前数组每个元素的当前位的数字进行入桶操作
for (int j = 0; j < len; j++)
{
int digNum = arr[j] / n % 10;//获取当前元素指定位数字
//放入对应桶
bucket[digNum][bucketNumCount[digNum]] = arr[j];
//对应桶中的元素个数加一
bucketNumCount[digNum]++;
}
//挨个取出桶中元素放入原来数组中
int index = 0;
//遍历每个桶,将桶中元素放入到原数组
for (int i = 0; i < 10; i++)
{
//如果当前桶内元素个数不为0,就全部倒出来
if (bucketNumCount[i] != 0)
{
for (int j = 0; j < bucketNumCount[i]; j++)
{
arr[index++] = bucket[i][j];//将第i个桶中的元素依次倒出
}
}
//当前桶内元素清空
bucketNumCount[i] = 0;
}
}
}
void test()
{
int arr[6] = { 53, 3, 542, 748, 14, 214 };
radixSort(arr, 6);
cout << "最终排序结果:" << endl;
for_each(arr, arr + 6, [](int val) {cout << val << " "; });
cout << endl;
}
int main()
{
test();
system("pause");
return 0;
}
计算整数位数的三种方法:
//法1:
int max=5000;
char str[100];
sprintf_s(str,"%d", max);
int maxlen = strlen(str);
//法2:
int max=5000;
int maxlen = 0;
while (max > 0)
{
max /= 10;
maxlen++;
}
cout << maxlen << endl;
int max=1000;
int maxlen = (int)(log10(max)) + 1;
cout << maxlen << endl;