基数排序法又称“桶子法”(bucketsort)或binsort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O(nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。
下面以LSD(按从低位到高位i的方式)为例说明这种排序的原理。
1.先按最低位将数据元素放入“桶”中。
2.将元素取出放入数组中(先取先放入的的元素),序列如下图所示
3.此时个位已经排好,接下来按十位进行上述操作,结果如下
4.再按百位排一次即可完成排序,结果如下
到这数据已经有序,接下来上代码:
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
//基数排序
//get max bit
int Getmaxbit(int *arr, int size)
{
int count = 1;
int radix = 10;
int i = 0;
for (; i < size; ++i)
{
while (arr[i] > radix)
{
count++;
radix *= 10;
}
}
return count;
}
void RadixSortLsd(int *arr, int size)
{
int MaxBitcount;//最大位数
int BitIndex = 0;
int radix = 10;
int i = 0;
MaxBitcount = Getmaxbit(arr, size);
int *bucket = (int*)malloc(sizeof(arr[0])*size);//创建一个"桶",其实是一个数组空间,为了方便理解而叫做桶
if (bucket == NULL)
return;
for (BitIndex = 0; BitIndex < MaxBitcount; BitIndex++)
{
int count[10] = { 0 };//放入函数内,每次初始化为0
int Addr[10] = { 0 };
//统计每个桶中有效元素个数
for(i = 0;i < size;++i)
{
count[arr[i] / radix % 10]++;
}
//计算每个桶的起始地址
for(i = 1;i < 10;++i)
{
Addr[i] = Addr[i - 1] + count[i - 1];
}
//将元素按地址放入桶中
for(i = 0; i < size; ++i)
{
int bucketNo = arr[i] / radix % 10;
bucket[Addr[bucketNo]++] = arr[i];①//为方便理解,代码后面有图解
}
//回收元素入桶
memcpy(arr, bucket, sizeof(arr[0])*size);
radix *= 10;
}
free(bucket);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
①:基数排序中的“桶”只是一个抽象的概念,可以将它想象为一个数组。希望可以通过这张图帮助理解: