基数排序(桶排序)
1.排序规则
将所有数据从前向后按照个位,十位,百位…(低位优先)依次全部存放到相应的桶内,然后再从桶内全部取出(放入或取出规则遵从队列,先进先出),跑的趟数,根据数据中的最大值的位数
例如:数据中的最大值是1234(最高位是千位),则需要将所有数据按千位,百位,十位,个位进行排序
2.图形示意
原始数据:12 32 2 620 42 98 122 289 987 37 56 90
第一次以个位进行排序跑一趟:
以个位进行排序最终结果:620 90 12 32 2 42 122 56 987 27 98 289(这些数据只看个位的话,有序)
第二次以十位进行排序跑一趟:
以十位进行排序最终结果:2 12 620 122 27 32 43 56 987 289 90 98(这些数据只看个位和十位的话,有序)
第三次以百位进行排序跑一趟:
以百位进行排序最终结果:2 12 27 32 43 56 90 98 122 620 289 987(完全有序)
3.代码实现
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//获取一个数组中最大值的位数
int Get_figure(int* arr, int len)
{
int max = 0;
for (int i = 0; i < len; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
int count = 0;
while (max != 0)
{
count++;
max /= 10;
}
return count;
}
//这个函数告诉我们传进来的参数n的,对应fin位是多少
//1234,2->2(1234,2的2表示要获取1234的百位也就是2) 345,1->4 0078,3->0
int Get_num(int n, int fin)
{
for (int i = 0; i < fin; i++)//这里代表需要n 先丢几位最低位
{
n = n / 10;//扔掉最低位
}
return n % 10;//此时获取剩余数据的最低位即可
}
//一趟桶排序 fin代表这一趟是根据哪个位进行排序(个,十,百....)
void Radix(int *arr, int len, int fin)
{
//先将10个桶申请好
int bucket[10][100] = { 0 };
int num[10] = { 0 };//num[1] 代表1号桶中有多少个有效值
//将所有数据从左往右向对应的桶中存放
for (int i = 0; i < len; i++)
{
int index = Get_num(arr[i], fin);
bucket[index][num[index]] = arr[i];
num[index]++;
}
//按照0->9号桶的顺序,依次遵循先进先出的规则将所有值取出来
int k = 0;
for (int i = 0; i <= 9; i++)//0->9号桶的顺序
{
for (int j = 0; j < num[i]; j++)//对应的桶内,从上往下取值
{
arr[k++] = bucket[i][j];//
}
}
}
//基数排序 时间复杂度O(d*n) 空间复杂度O(d*n) 稳定性:不稳定
void RadixSort(int* arr, int len)
{
//assert
//1.首先需要知道 数据中最大值有多少位
int count = Get_figure(arr, len);
for (int i = 0; i < count; i++)
{
Radix(arr, len, i);
}
}
int main()
{
int arr[] = { 12,2,39,88,4,6,25,232,62,221 };
RadixSort(arr, sizeof(arr) / sizeof(arr[0]));
Show(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
4.测试结果
5.复杂度分析
时间复杂度:O(dn)
空间复杂度:O(dn)
稳定性:不稳定