一. 实现原理
基数排序的相关知识,参考漫画:什么是基数排序?
二. 具体实现
实现中,使用vector作为桶,只是从编码便利的角度出发。
辅助函数
// 获取data的位数
int GetBitCount(int data)
{
int curCount = 0;
while (data != 0)
{
++curCount;
data = data / 10;
}
return curCount;
}
// 获取某个数的某一位的值,certainBit 1表示个位,2表示十位,依次类推
int GetDataInBit(int data, int certainBit)
{
int remainder = 0;
while (certainBit-- != 0)
{
remainder = data % 10;
data = data / 10;
}
return remainder;
}
// 获取数组中元素的最大位数
int GetMaxBitCount(int* pData, int size)
{
int maxBitCount = 0;
for (int idx = 0; idx < size; ++idx)
{
int curBitCount = GetBitCount(pData[idx]);
if (curBitCount > maxBitCount) maxBitCount = curBitCount;
}
return maxBitCount;
}
最终实现
void RadixSort(int* pData, int size)
{
if (nullptr == pData || size < 1) return;
std::vector<std::vector<int>> tempTables(10); // 总共10个桶
for (int curBit = 1; curBit <= GetMaxBitCount(pData, size); ++curBit) // 从最低为1到最高位maxBitCount
{
for (int idx = 0; idx < size; ++idx)// 将各个元素根据当前位的数字分到各个桶
{
int curData = GetDataInBit(pData[idx], curBit);
tempTables[curData].push_back(pData[idx]);
}
int curIdx = 0; // 将桶中元素写回到原数组
for (auto& curTable : tempTables)
{
for (int curData : curTable) pData[curIdx++] = curData;
curTable.clear(); // 清空vector
}
}
}
三. 输出验证
加上相关的输出信息后再进行调用。
辅助函数
void Print(int* pData, int size)
{
for (int idx = 0; idx < size; ++idx) std::cout << pData[idx] << " ";
std::cout << std::endl;
}
初始数据为
int datas[30] = { 41 167 34 100 269 124 78 258 262 164 5 245 181 27 61 191 295 242 27 36 291 204 2 153 292 82 21 116 218 95 };
输出版本
void RadixSort_Output(int* pData, int size)
{
if (nullptr == pData || size < 1) return;
std::vector<std::vector<int>> tempTables(10); // 总共10个桶
int maxBitCount = GetMaxBitCount(pData, size);
for (int curBit = 1; curBit <= maxBitCount; ++curBit) // 从最低为1到最高位maxBitCount
{
for (int idx = 0; idx < size; ++idx)// 将各个元素根据当前位的数字分到各个桶
{
int curData = GetDataInBit(pData[idx], curBit);
tempTables[curData].push_back(pData[idx]);
}
std::cout << std::endl << "CUR BIT " << curBit << std::endl;
for (int idx = 0; idx < (int)tempTables.size(); ++idx)
{
auto& curTable = tempTables[idx];
std::cout << std::endl << "BUCKET " << idx << std::endl;
Print(curTable.data(), (int)curTable.size());
}
int curIdx = 0; // 将桶中元素写回到原数组
for (auto& curTable : tempTables)
{
for (int curData : curTable) pData[curIdx++] = curData;
curTable.clear();
}
std::cout << "WRITE BACK " << std::endl;
Print(pData, size);
}
}
调用输出
INIT DATA // 初始数据
41 167 34 100 269 124 78 258 262 164 5 245 181 27 61 191 295 242 27 36 291 204 2 153 292 82 21 116 218 95
CUR BIT 1 // 开始按个个位进行分桶
BUCKET 0 // 0号桶
100
BUCKET 1 // 1号桶
41 181 61 191 291 21
BUCKET 2 // 2号桶
262 242 2 292 82
BUCKET 3 // 3号桶
153
BUCKET 4 // 4号桶
34 124 164 204
BUCKET 5 // 5号桶
5 245 295 95
BUCKET 6 // 6号桶
36 116
BUCKET 7 // 7号桶
167 27 27
BUCKET 8 // 8号桶
78 258 218
BUCKET 9 // 9号桶
269
WRITE BACK // 将桶中元素写回到远数组
100 41 181 61 191 291 21 262 242 2 292 82 153 34 124 164 204 5 245 295 95 36 116 167 27 27 78 258 218 269
CUR BIT 2 // 开始按十位进行分桶
BUCKET 0
100 2 204 5
BUCKET 1
116 218
BUCKET 2
21 124 27 27
BUCKET 3
34 36
BUCKET 4
41 242 245
BUCKET 5
153 258
BUCKET 6
61 262 164 167 269
BUCKET 7
78
BUCKET 8
181 82
BUCKET 9
191 291 292 295 95
WRITE BACK
100 2 204 5 116 218 21 124 27 27 34 36 41 242 245 153 258 61 262 164 167 269 78 181 82 191 291 292 295 95
CUR BIT 3 // 开始按百位进行分桶
BUCKET 0
2 5 21 27 27 34 36 41 61 78 82 95
BUCKET 1
100 116 124 153 164 167 181 191
BUCKET 2
204 218 242 245 258 262 269 291 292 295
BUCKET 3
BUCKET 4
BUCKET 5
BUCKET 6
BUCKET 7
BUCKET 8
BUCKET 9
WRITE BACK
2 5 21 27 27 34 36 41 61 78 82 95 100 116 124 153 164 167 181 191 204 218 242 245 258 262 269 291 292 295
FINAL DATA // 最终数据
2 5 21 27 27 34 36 41 61 78 82 95 100 116 124 153 164 167 181 191 204 218 242 245 258 262 269 291 292 295