目录
一、概述
1、基本思想(沿袭自桶排序):
从低位开始,对所有数字进行排序。例如第1轮排序后,数字的个位数要有序;第2轮排序后,数字的十位数要有序,如果十位数相同的数,个位数要按照之前的相对顺序摆放;依次类推直至最高位排序完成。过程如下图:
二、代码
C++利用vector实现
/*======================================================
*
*程序说明: C++基数排序实现
*运行平台: Linux/Windows
*创建日期: 20190831
*作 者: LiuHuan
*
*======================================================*/
#include <iostream>
#include <vector>
#include <time.h> // 随机数种子
#include <chrono> // 统计运行时间需要
using namespace std;
using namespace chrono;
#define RUN_SORT(FUNC) \
{ \
auto tStart = system_clock::now(); \
FUNC; \
auto tEnd = system_clock::now(); \
auto tCost = duration_cast<nanoseconds>(tEnd - tStart); \
cout << "耗时: " << tCost.count() << " ns(纳秒).\n" << endl; \
}
// 随即返回正负
int Symbol(int num)
{
return (num == 1 ? 1 : -1);
}
void CardinalitySort(vector<int>& vec)
{
// 1、确定最大值
int maxValue = vec[0];
for (auto it : vec)
{
maxValue = maxValue >= it ? maxValue : it;
}
// 2、确定最大值位数
int maxNumLength = 0;
for (int i = maxValue; i != 0; i /= 10)
{
maxNumLength++;
}
// 3、借用桶排序思想
int mod = 10, dev = 1;
// 根据最大位数, 就有几轮建桶过程, 依次从个位到最高位建桶
for (size_t i = 0; i < maxNumLength; i++, dev *= 10, mod *= 10)
{
vector<vector<int> > vecBucket; // 该轮的桶
// 桶初始化, 只需要十个桶(根据该位“数值”入0 - 9号桶)
// 若还需考虑负值, 桶个数扩大一倍(20个桶), 前0-9存取负数, 后10-19存取正数
for (size_t i = 0; i < 20; i++)
{
vector<int> vecTmp;
vecBucket.push_back(vecTmp);
}
// 数据入桶
for (size_t j = 0; j < vec.size(); j++)
{
int bucketIndex = ((vec[j] % mod) / dev) + 10; // 该位数值即为该入的桶编号
vecBucket[bucketIndex].push_back(vec[j]);
}
vec.clear();
for (auto itBucket : vecBucket)
{
for (auto itNum : itBucket) // 注意itBucket也是一个vector
{
vec.push_back(itNum);
}
}
}
}
template<typename T>
void printVec(const vector<T>& vec)
{
int cnt = 1;
for (auto it : vec)
{
cout << it << "\t";
if (cnt++ % 10 == 0) // 每十个换行输出
{
cout << "\n";
}
}
cout << "\n\n";
}
int main()
{
srand((unsigned int)time(NULL));
int cnt = 1;
do
{
vector<int> vec;
for (size_t i = 0; i < 10; i++) // 注意这里元素值和序列大小的选取对排序性能有影响,建议读者自己改变参数调试, 研究一番
{
int value = Symbol(rand() % 2) * rand() % 1000;
vec.push_back(value);
}
cout << "************第[ " << cnt << " ]次基数排序前序列:\n";
printVec(vec);
RUN_SORT(CardinalitySort(vec))
cout << "基数排序后序列:\n";
printVec(vec);
} while (cnt++ < 5);
//system("pause"); // linux关闭,VS打开
return 0;
}
三、程序运行情况