基数排序

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);//重新初始化
  

以上是关于基数排序的主要内容,如果未能解决你的问题,请参考以下文章

算法知识详解基数排序算法

基数排序

可视化基数排序

#19 基数排序(Radix Sort)

排序算法——基数排序

C++ 简单实现基数排序(list容器)