基数排序 (Radix sort)

参考: http://en.wikipedia.org/wiki/Radix_sort#Definition


基数排序,可以理解成多关键字排序。(因此在排序的时候需要用到稳定的排序算法,如计数排序

它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

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

An example

Original, unsorted list:

170, 45, 75, 90, 802, 24, 2, 66

Sorting by least significant digit (1s place) gives: [*Notice that we keep 802 before 2, because 802 occurred before 2 in the original list, and similarly for pairs 170 & 90 and 45 & 75.]

17 0, 9 0, 80 2, 2, 2 4, 4 5, 7 5, 6 6   个位

Sorting by next digit (10s place) gives: [*Notice that 802 again comes before 2 as 802 comes before 2 in the previous list.]

8 02, 2, 24, 45, 66, 1 70, 75, 90   十位( 保证 170 在 90 前面)

Sorting by most significant digit (100s place) gives:

2, 24, 45, 66, 75, 90, 170, 802   百位
(也就是先根据个位数进行排序,再根据十位,在根据百位等等。 但是要保证上一次排序中,“相同”元素的顺序。所以必须使用一个稳定的排序算法。如计数排序)

阅读了wiki上的代码,加了点注释,记录在下:

/*
	基数排序
	转自wiki: radix sort
*/

#include <stdio.h>
#define MAX 5
//#define SHOWPASS
void print(int *a, int n)
{
  int i;
  for (i = 0; i < n; i++)
    printf("%d\t", a[i]);
}
 
void radixsort(int *a, int n)
{
  int i, b[MAX], m = a[0], exp = 1;

  // m = a数组中最大的数字。用来控制下面的循环次数。
  for (i = 0; i < n; i++)
  {
    if (a[i] > m)
      m = a[i];
  }
 
  while (m / exp > 0)
  {
    int bucket[10] ={  0 }; 	//bucket清零
    for (i = 0; i < n; i++)
      bucket[a[i] / exp % 10]++; // a[i] / exp % 10 该表达式是求a[i]的个位数字(exp=1)、十位数字(exp=10)、百位数字(exp=100)......
				 // bucket[0..9] 统计各位数字的个数
    for (i = 1; i < 10; i++)
      bucket[i] += bucket[i - 1];// 用意是体现0~9, 权重越来越大。(更严格的说是存储比它本身小的数字的个数,见counting sort)
    for (i = n - 1; i >= 0; i--)
      b[--bucket[a[i] / exp % 10]] = a[i]; // 根据a[i]的最低位,找到它的排名
    for (i = 0; i < n; i++)
      a[i] = b[i];
    exp *= 10;	// 比较下一位, 或者说比较下一个关键字
 
    #ifdef SHOWPASS
      printf("\nPASS   : ");
      print(a, n);
    #endif
  }
}
 
 
int main()
{
  int arr[MAX];
  int i, n;
 
  printf("Enter total elements (n < %d) : ", MAX);
  scanf("%d", &n);
 
  printf("Enter %d Elements : ", n);
  for (i = 0; i < n; i++)
    scanf("%d", &arr[i]);
 
 
  printf("\nARRAY  : ");
  print(&arr[0], n);
 
  radixsort(&arr[0], n);
 
  printf("\nSORTED : ");
  print(&arr[0], n);
  printf("\n");
 
  return 0;
}


/*
条件宏:
可以用来当做开关使用。
在调试的时候打开开关,输出更多信息,以便观察程序的运行。
在调试完成之后,关闭开关即可。

1)在编译的时候定义宏,使用gcc 的 -D选项。详见man gcc
gcc -Wall radix_sort.c -D SHOWPASS
2)或者在源文件中直接定义宏
#define SHOWPASS

*/

注 : 此radix sort使用了 conuting sort算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值