【数据结构学习记录29】——基数排序

一.原理

所谓的基数排序的基数,就是我们讲进制时候的那个基数。比如十进制的基数就是10,二进制的基数就是2。其中,从右向左开始第n位,实际上表示的是基数的n次方倍。比如1012表示 1 ⋅ 2 0 + 0 ⋅ 2 1 + 1 ⋅ 2 2 1\cdot2^0+0\cdot2^1+1\cdot2^2 120+021+122
那么,我们可以通过先比较某一位,进行排序,然后再比较另一位进行排序,直到排完所有的位数。比如我们以LSD低位优先法,从右往左一位一位的比较;或者MSD高位优先法,从左到右一位一位的比较,从左往右一位一位的比较。
过程:

  1. 创建基数个队列,下标从0开始。
  2. 取关键字某位的值,存入对应编号的队列(有点像哈希表)
  3. 从0或者从基数-1的队列开始,递增或递减出队,这样出队构成的顺序表、链表是某位有序的。
  4. 重复更改位数,并2、3,直到所有位都有序,最后出队的队列就有序。

二.过程

一般我们用的都是10进制,所以采取基数为10更直观。
假设我们对这些数以低位优先的方式排序:
在这里插入图片描述
对低位进行排序:
在这里插入图片描述
对次低位排序:
在这里插入图片描述
再次低位:
在这里插入图片描述
这样就拍好了。

三.代码

代码很很很简单,所以就不想写了,抄个代码,菜鸟教程 1.10 基数排序

#include<stdio.h>
#define MAX 20
//#define SHOWPASS
#define BASE 10

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[BASE] = {
    
     0 };

    for (i = 0; i < n; i++) {
    
    
      bucket[(a[i] / exp) % BASE]++;
    }

    for (i = 1; i < BASE; i++) {
    
    
      bucket[i] += bucket[i - 1];
    }

    for (i = n - 1; i >= 0; i--) {
    
    
      b[--bucket[(a[i] / exp) % BASE]] = a[i];
    }

    for (i = 0; i < n; i++) {
    
    
      a[i] = b[i];
    }

    exp *= BASE;

#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;
}

猜你喜欢

转载自blog.csdn.net/u011017694/article/details/111564378