基数排序

基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD

的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。 
  以LSD为例,假设原来有一串数值如下所示: 
  73, 22, 93, 43, 55, 14, 28, 65, 39, 81 
  首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中: 
  0 
  1 81
  2 22 
  3 73 93 43 
  4 14 
  5 55 65 
  6 
  7 
  8 28 
  9 39 
  接下来将这些桶子中的数值重新串接起来,成为以下的数列: 
  81, 22, 73, 93, 43, 14, 55, 65, 28, 39 
  接着再进行一次分配,这次是根据十位数来分配: 
  0 
  1 14 
  2 22 28 
  3 39 
  4 43 
  5 55 
  6 65 
  7 73 
  8 81 
  9 93 
  接下来将这些桶子中的数值重新串接起来,成为以下的数列: 
  14, 22, 28, 39, 43, 55, 65, 73, 81, 93 
  这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数

为止。 
  LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好,MSD的方式恰与LSD

相反,是由高位数为基底开始进行分配,其他的演算方式则都是相同。 
效率分析
  时间效率:设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的

时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(n),共进行d

趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。 
实现的方法
  最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关

键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关

键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。 
  最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序

,依次重复,直到对k1排序后便得到一个有序序列。 
C
  #include <stdio.h> 
  #include <stdlib.h> 
  int main(){ 
  int data[10]={73,22,93,43,55,14,28,65,39,81}; 
  int temp[10][10]={0}; 
int order[10]={0}; 
  int i,j,k,n,lsd; 
  k=0;n=1; 
  printf("\n排序前: "); 
  for (i=0;i<10;i++) printf("%d ",data[i]); 
  putchar('\n'); 
  while (n<=10){ 
  for (i=0;i<10;i++){ 
  lsd=((data[i]/n)%10); 
  temp[lsd][order[lsd]]=data[i]; 
  order[lsd]++; 
  } 
  printf("\n重新排列: "); 
  for (i=0;i<10;i++){ 
  if(order[i]!=0) 
  for (j=0;j<order[i];j++){ 
  data[k]=temp[i][j]; 
  printf("%d ",data[k]); 
  k++; 
  } 
  order[i]=0; 
  } 
  n*=10; 
  k=0; 
  } 
  putchar('\n'); 
  printf("\n排序后: "); 
  for (i=0;i<10;i++) printf("%d ",data[i]); 
  return 0; 
  }

posted @ 2013-10-14 14:00  smart0326  阅读(340)  评论(0)    收藏  举报