基数排序
Posted 遥远的歌s
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基数排序相关的知识,希望对你有一定的参考价值。
基数排序
算法思想:给定的一组数据,想按照个位数开始排序,放入对应序号桶中,然后统一取出后,再按十位数大小继续放入对应的桶中……依次类推,直到全部数据有序。
看一个例子:对数组56,78,12,248,103,89,34进行排序
步骤:
首先,按照每个数据的个位数进行排序得下图
重新整理后得到arr为:12,2,103,34,56,78,48,89
再按照十位数大小进行排序,得如下图
整理后得到arr:2,103,12,34,48,56,78,89
最后按照百位数进行排序得下图:
最终得到有序数列
2,12,34,48,56,78,89,103。
综上不难看出,排序得趟数为待排序数组中最大数得位数,上述例子中最大数为103,所以需要排3次序,才能得到最终有序数列。
定义桶号的意义
这里的桶号,其实可以理解成一个计数器,它是记录每一个桶号下的元素的个数,它为每趟排完序的数列中每一个元素应该放的位置提供了帮助。
这里举上面例子中第一趟排完序的例子:
首先,先将每一个桶号下标为1的数据开始,依次加上它前一个下标下的数据,即下图
这里需要从后向前开始确定每一个数据的位置,待排序的数组中最后一个元素是34,它在排完一趟后的的数组中的位置是3,这个3是通过34按个位数对应的桶号即4,桶号4中的数据-1得到的,即4-1=3,同理89的位置是7,是通过89按个位对应的桶号中的数据8-1=7得到的,依次类推,就可以确定每一个数据在排完序后的数组中的对应位置。每次确定一个数据后,bucket中对应桶号中的数据要自减1。这里桶号中的数据指的是上图中最下面红色一行的数据
算法实现
//确定待排序数组中最大数的位数
int GetMaxNumSeat(vector<int> arr)
int max = arr[0];
int num = 0;
for(int i = 1;i<arr.size();i++)
if(max < arr[i])
max = arr[i];
while(max)
num++;
max/=10;
return num;
void RadixSort(vector<int> &arr)
int num = GetMaxNumSeat(arr);//获取最大数的位数
vector<int> tmp;//中间变量存访临时数据
tmp.resize(arr.size(),0);//初始化
int idx = 1;//开始获取最低位
int number;//计算每次的桶号
for(int i = 0;i<num;i++)
vector<int> bucket;//j计数器
bucket.resize(10,0);//初始化
for(int j = 0;j<arr.size();j++)
number = (arr[j] / idx) % 10;//获取个位,十位.....以此类推
bucket[number]++;//记录每一个位置的元素个数
//依次累加方便后续记录位置
for(int k = 1;k<10;k++)
bucket[k] = bucket[k - 1] + bucket[k];//将每一位的元素次数加起来,方便后续找寻每个元素的位置
//从后向前记录位置
for(int j = arr.size() - 1;j >= 0;j--)
number = (arr[j] / idx) % 10;获取个位,十位.....依次找桶号
tmp[bucket[number] - 1] = arr[j];//将每个数对应排完序的位置赋给临时数组tmp
bucket[number]--;//计数器减1
swap(arr,tmp);//交换arr和tmp
idx*=10;//idx扩大10倍寻找下一位数
bucket.clear();//每次循环要把bucket清空一次
tmp.clear();//中间临时数组清空
tmp.resize(arr.size(),0);//重新初始化
以上是关于基数排序的主要内容,如果未能解决你的问题,请参考以下文章