写在前面
今天开始学习后缀数组,发现了这个神奇的基数排序,之前只是在数据与结构上了解了基数排序的实现原理,但是对于程序怎么实现到现在还是不知道,但是还是想写一篇关于后缀数组的博客,所以就从这里开始写起吧,我们重点是在程序的实现上,原理等的内容只是提一下。
实现原理
基数排序的原理:首先根据个位上的数字将数组进行排序,将他们分配到0-9号桶中,然后我们将桶中的数字串起来,接着再次按照十位上的数字进行分配,再次分配到0-9这是个桶中,我们再将这些数字串起来,我们会持续进行这个过程,直到最高的数位为止。
我们可以举个栗子看一下:
比如我们有数组{78 , 56 , 89 , 45 , 23 ,12 ,79 , 46 ,13}
我们先按照个位进行排序:
然后将他们每个桶中的数字串起来:{12,23, 13, 45, 56, 46, 78, 89, 79};
然后按照十位上的数字进行排序:
然后我们将每个桶中的数字串起来:{12,13,23,45,46,56,78,79,89};
这样我们就得到了这个正确的顺序,如果我们有跟高的位数,那么就一直重复这两个步骤,一直到最高位......
C++实现
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN = 1000;
int data[MAXN];
int tmp[MAXN];
int count[MAXN]; //计数数组
int maxbit(int data[], int n)
{
int max_num = 1;
int num = 10;
for(int i = 0;i < n;i ++)
{
while(data[i] >= num)
{
num *= 10;
max_num ++;
}
}
return max_num;
}
void RadixSort(int data[], int n)
{
/**
函数说明:实现基数排序
参数说明:
data:数据数组
n:data数组的最高位
**/
int d = maxbit(data,n); //得到数组中最高的位数
int radix = 1;
for(int i =0 ;i < d;i ++) //进行d次排序
{
for(int j =0 ;j < 10;j ++) // 首先进行清桶的操作
count[j] = 0;
for(int j =0 ;j < n;j ++)
{
int k = (data[j] / radix) % 10; //统计每个桶中含有数字的数量
count[k] ++;
}
for(int j =1 ;j < 10;j ++)
count[j] += count[j-1]; //将tmp中的位置依次分配给每个桶,意思就是为每个桶里面还有的数量都留下够用的空间
//这里想不明白可以理解为相邻两个数位之间的差表示的就是给这个桶分配的空间;
for(int j = n - 1; j >= 0;j --)//将桶中的记录依次收集到tmp中
{
int k = (data[j] / radix) % 10; //得到他在哪一个桶里面
tmp[count[k] - 1 ] = data[j]; //因为上面已经给这个桶留下了相应的空间,所以只需要一次向后减1,就可以排到适当的位置
count[k] -- ;
}
for(int j = 0;j < n;j ++) //将临时数组的内容复制到data数组中
{
data[j] = tmp[j];
}
radix *= 10;
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i =0 ;i < n;i ++)
scanf("%d",&data[i]);
RadixSort(data,n);
for(int i =0 ;i < n;i ++)
printf("%d%c",data[i],i==n-1?'\n':' ');
return 0;
}
我们就先说基数排序就先到这里,我们后面会继续更新关于后缀数组的具体实现。
如果有错误,欢迎大家在下面评论区评论,谢谢!
参考文献
基数排序百度百科 https://baike.baidu.com/item/%E5%9F%BA%E6%95%B0%E6%8E%92%E5%BA%8F/7875498?fr=aladdin#1_1