Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1019728
  • 博文数量: 297
  • 博客积分: 11721
  • 博客等级: 上将
  • 技术积分: 3431
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-25 10:21
文章分类

全部博文(297)

文章存档

2016年(9)

2011年(71)

2010年(137)

2009年(80)

分类: C/C++

2010-06-09 14:06:22

简介

  (radix sort)则是属于分配式排序distribution sort),基数排序法又称桶子法bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。

[]

解法

  基数排序的方式可以采用LSDLeast significant digital)或MSDMost significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

  以LSD为例,假设原来有一串数值如下所示:

  73, 22, 93, 43, 55, 14, 28, 65, 39, 81

  首先根据个位数的数值,在走访数值时将它们分配至编号09的桶子中:

  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(radix),共进行d趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。

[]

实现方法

  最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分 组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

  最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

[]

实作

  * C

  #include

  #include

  int main(void) {

  int data[10] = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81};

  int temp[10][10] = ;

  int order[10] = ;

  int i, j, k, n, lsd;

  k = 0;

  n = 1;

  printf("\n排序前: ");

  for(i = 0; i < 10; i++)

  printf("%d ", data);

  putchar('\n');

  while(n <= 10) {

  for(i = 0; i < 10; i++) {

  lsd = ((data / n) % 10);

  temp[lsd][order[lsd]] = data;

  order[lsd]++;

  }

  printf("\n重新排列: ");

  for(i = 0; i < 10; i++) {

  if(order != 0)

  for(j = 0; j < order; j++) {

  data[k] = temp[j];

  printf("%d ", data[k]);

  k++;

  }

  order = 0;

  }

  n *= 10;

  k = 0;

  }

  putchar('\n');

  printf("\n排序后: ");

  for(i = 0; i < 10; i++)

  printf("%d ", data);

  return 0;

  }

  * Java

  public class RadixSort {

  public static void sort(int[] number, int d) {

  int k=0;

  int n=1;

  int m=1;

  int[][] temp = new int[number.length][number.length];

  int[] order = new int[number.length];

  while(m <= d) {

  for(int i = 0; i < number.length; i++) {

  int lsd = ((number[i] / n) % 10);

  temp[lsd][order[lsd]] = number[i];

  order[lsd]++;

  }

  for(int i = 0; i < d; i++) {

  if(order[i] != 0)

  for(int j = 0; j < order[i]; j++) {

  number[k] = temp[i][j];

  k++;

  }

  order[i] = 0;

  }

  n *= 10;

  k = 0;

  m++;

  }

  }

  public static void main(String[] args) {

  int[] data =

  {73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100};

  RadixSort.sort(data, 10);

  for(int i = 0; i < data.length; i++) {

  System.out.print(data[i] + " ");

  }

  }

阅读(530) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~