radix-sort

转自算法导论中文版

代码转自http://en.wikipedia.org/wiki/Radix_sort

答案转自http://home.ustc.edu.cn/~sunqi622/down/sfdlda.pdf


基数排序(radix sort)是一种用在老师穿卡机上的算法。一张卡片有80列,每一列可以在12个位置中的任一处穿孔。排序器可以被机械的“程序化”,以便对一叠卡片中的每一列进行检查,再根据穿孔的位置将它们分别入12个盒子里。这样,操作员就可以逐个地将它们收集起来,其中第一个位置穿孔的放在最上面,第二个位置穿孔的其次,等等。


对十进制数字来说,每列中只用到10个位置。一个d位数占用d个列。因为卡片排序器一次只能查看一个列,因此,要对n张卡片上的d位数进行排序,就需要用到排序算法。


基数排序是首先按最低有效位数字进行排序,以解决卡片排序问题。仅需d遍就可以将一叠卡片排好序。


关于这个算法,很重要的一点就是按位排序要稳定。有卡片排序器所做的排序时稳定的,但操作员在把卡片从盒子里拿出来时不能改变它们的次序,即使某一个盒子中所有卡片在给定列上的川空位置都相同也要注意这一点。


基数排序算法的代码是很直观的。在下面的过程中,假设长度为n的数组A中,每个元素都是d位数字,其中第一位是最低位,did位是最高位。

伪代码

RADIX-SORT(A, d)

    for i <- 1 to d

        do use a stable sort to sort array A on digit i


引理3

给定n个d位数,每一个数位可以取k种可能的值。基数排序算法能以Θ(d(n+k))的时间正确地对这些数进行排序。


引理4

给定n个b位数和任何正整数r<=b,RADIX-SORT能在Θ((b/r)(n+2^r))时间内正确地对这些数进行排序。


算法导论

8.3-4
Show how to sort n integers in the range 0 to n^2 -1in O(n) time.

Treat the numbers as 2-digit numbers in radix n, each digit ranges from 0 to n-1. so these 2-digit numbers with radix sort, There are 2 call to counting sort, each taken O(n+n) = O(n) times, so the total sort time is O(n)

根据引理3,为了使算法时间复杂度为O(n), 应使k=O(n),

根据引理4,k=2^r,有n=2^r,r=lg(n)。数据应该至少有b = lg(n^2) = 2*lgn;d = b/r = 2*lg(n)/lg(n) = 2。

所以当取d=2时,算法时间复杂度是O(n)。


Give the asymptotically fastest algorithm you can to sort n integers in the range of 0 to(n^4)−1.
You should give a very clear and complete high-level description of your algorithm.Besure to
analyze the time complexity of your algorithm as a function of n. You are NOT restricted to
use acomparison sorting algorithm (although are welcome to if youwant).
Here is an O(n) algorithm for this problem. Since anysorting algorithm must at least access
each integer, this algorithm is asymptotically optimal.
We use radix sort where we represent each number as a 4 digit base-nnumber. Thus the time
complexity is O(d(n+k))=O(4(n+n))=O(n) since d=4 and k=n.
If you saw the above solution right away that's great.Here's a way to have solved this otherwise.
Each element requires roughly log2(n^4)=4log2n bits. (The exact number is $4log2n%). Suppose
you grouped b bits per digit. Then there would be d=$(4log2n)/b% digits each which takes on
oneof 2^b values. Hence the time complexity for radix sort is

  
  
O(d(n+k))=O(4log2n/b(n+2^b)).
At this point you could minimize this function with respect to b. However, if we think about it a little, we can find a value of b that gives us an asymptotically optimal solutions. Since,the time complexityh as the term (n+2^b), asymptotically we can't do better than picking b such that 2^b =n(and hence b=log2n). By doing this we obtain a time complexity of O(4(2n))=O(n) which is clearly asymptotically optimal. Once you've done this, you can then look back and see that you picked a base-n representation and thus give the two line solution given above.


C代码中的稳定排序算法使用了计数算法


#include<stdio.h>

#define MAX 8
#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;
  for (i = 1; i < n; i++)
  {
    if (a[i] > m)
      m = a[i];
  }
 
  while (m / exp > 0)
  {
    int bucket[10] ={  0 };
    for (i = 0; i < n; i++)
      bucket[(a[i] / exp) % 10]++;
    for (i = 1; i < 10; i++)
      bucket[i] += bucket[i - 1];
    for (i = n - 1; i >= 0; i--)
      b[--bucket[(a[i] / exp) % 10]] = 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);
  n = n < MAX ? n : MAX;
 
  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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值