Radix Sort 基数排序

22 篇文章 0 订阅
  • 1.基本思想
  • 实现排序主要是通过关键字间的比较和移动记录这两种操作,而实现基数排序不需要进行记录关键字间的比较,它是一种利用多关键字排序的思想,即借助"分配"和"收集"两种操作对单逻辑关键字进行排序的方法。
  • 基数排序的方法是:一个逻辑关键字可以看成由若干个关键字复合而成的,可把每个排序关键字看成是一个d元组:
  • 例如,如果关键字是数值,且其值在0~99范围内,则可把每一个十进制数字看成是一个关键字,即可认为K由2个关键字(K0,K1)组成,其中K0是十位数,K1是个位数。排序时先按 的值从小到大将记录分配到r个盒子中,然后依次收集这些记录,再按 的值分配到r个盒子中,如此反复,直到对分配后收集起来的序列,便是完全排序的状态,其中r称为基数。这个过程是按LSD(最低位优先法)进行排序的,即从最低数位关键字起,按关键字的不同值对序列中记录" 分配"和"收集"的。基数的选择和关键字的分解法因关键字的类型而异。
  • 为了实现记录的"分配"和"收集",需设立r个队列,排序前将队列设置为空,分配时,将记录插入到各自的队列中去,收集时将这些队列中记录排在一起。
  • 一般采用静态链表作为记录序列的存储结构,并且不另外设置各链队列的结点空间,而是利用静态链表中的结点作为链队列中的结点,这样只需修改指针即可完?quot;分配"和"收集"任务。时间复杂度为O(d(n+rd))
  • 在基数排序算法中,没有进行关键字的比较和记录的移动,而只是顺链扫描链表和进行指针赋值,所以,排序的时间主要耗费在修改指针上。对于n个记录(假设每个记录含d个关键字,每个关键字的取值范围为rd个值)进行一趟分配的时间复杂度为O(n),进行一趟收集的时间复杂度为O(rd),整个排序过程需要进行 d趟分配和收集操作。因此,链式基数排序总的时间复杂度为O(d(n+rd))。
  • 当n较小,d较大时,基数排序并不合适。只有当n较大,d较小时,特别是记录的信息量较大时,基数排序最为有效。基数排序中所需辅助空间为2rd个队列指针,另外每个记录中都增加了一个指针域。

 

 

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std; 
  4. // constant size must be defined as the array size for bucketSort to work 
  5. const int SIZE = 12; 
  6. void bucketSort( int [] );
  7. void distributeElements( int [], int [][ SIZE ], int );
  8. void collectElements( int [], int [][ SIZE ] );
  9. int numberOfDigits( int [], int );
  10. void zeroBucket( int [][ SIZE ] ); 
  11. int main() 
  12. {
  13.      int array[ SIZE ] = { 19, 13, 5, 27, 1, 26, 31, 16, 2, 9, 11, 21 };
  14.      cout << "Array elements in original order:/n";
  15.      for ( int i = 0; i < SIZE; ++i )
  16.           cout << setw( 3 ) << array[ i ];
  17.      cout << '/n';
  18.      bucketSort( array );
  19.      cout << "/nArray elements in sorted order:/n";
  20.      for ( int j = 0; j < SIZE; ++j )
  21.          cout << setw( 3 ) << array[ j ];
  22.      cout << endl; 
  23.      system("pause");
  24.      return 0;
  25. // Perform the bucket sort algorithm 
  26. void bucketSort( int a[] )
  27. {
  28.      int totalDigits, bucket[ 10 ][ SIZE ] = { 0 };
  29.      totalDigits = numberOfDigits( a, SIZE );
  30.      for ( int i = 1; i <= totalDigits; ++i ) 
  31.      {
  32.          distributeElements( a, bucket, i );
  33.           collectElements( a, bucket );
  34.           if ( i != totalDigits )
  35.               zeroBucket( bucket ); // set all bucket contents to zero
  36.      }
  37. // Determine the number of digits in the largest number 
  38. int numberOfDigits( int b[], int arraySize )
  39. {
  40.     int largest = b[ 0 ], digits = 0;
  41.     for ( int i = 1; i < arraySize; ++i )
  42.         if ( b[ i ] > largest )
  43.             largest = b[i];
  44.     while ( largest != 0 ) 
  45.     {
  46.          ++digits;
  47.          largest /= 10;
  48.     }
  49.     return digits;
  50. // Distribute elements into buckets based on specified digit 
  51. void distributeElements( int a[], int buckets[][ SIZE ], int digit )
  52. {
  53.      int divisor = 10, bucketNumber, elementNumber;
  54.      for ( int i = 1; i < digit; ++i ) // determine the divisor
  55.          divisor *= 10; // used to get specific digit
  56.      for ( int k = 0; k < SIZE; ++k ) 
  57.      { // bucketNumber example for hundreds digit:
  58.          // (1234 % 1000 - 1234 % 100) / 100 --> 2
  59.          bucketNumber = ( a[ k ] % divisor - a[ k ] %( divisor / 10 ) ) / ( divisor / 10 );
  60.          // retrieve value in buckets[bucketNumber][0] to determine
  61.          // which element of the row to store a[i] in.
  62.          elementNumber = ++buckets[ bucketNumber ][ 0 ];
  63.          buckets[ bucketNumber ][ elementNumber ] = a[ k ];
  64.      }
  65. // Return elements to original array 
  66. void collectElements( int a[], int buckets[][ SIZE ])
  67. {
  68.      int subscript = 0;
  69.      for ( int i = 0; i < 10; ++i )
  70.           for ( int j = 1; j <= buckets[ i ][ 0 ]; ++j )
  71.               a[ subscript++ ] = buckets[ i ][ j ];
  72. // Set all buckets to zero 
  73. void zeroBucket( int buckets[][ SIZE ] )
  74. {
  75.     for ( int i = 0; i < 10; ++i )
  76.          for ( int j = 0; j < SIZE; ++j )
  77.               buckets[ i ][ j ] = 0;
  78. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值