【数据结构学习记录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;
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

康娜喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值