基数排序

14 阅读2分钟

原理概念

基数排序也成为桶排序

数据处理步骤

  • 找出最长的数字,确定要处理的桶排序的次数(最长的数字代表要处理的次数)
  • 依次由个位开始,把相应位数上的数字放入相应的序号的桶里面,完成后再按照桶的序号,依次取出桶里面的数据,放回原始的数组中。
  • 当处理完所有的位数,最终得到有序的序列

时间空间复杂度

排序算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度稳定性
基数排序O(nd)O(nd)O(nd)O(n)稳定

d为数据的最大的位数。

代码

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <vector>
using namespace std;

void RadixSort(int arr[], int size) {
  int maxData = arr[0];  // 获取数组中的最大值
  for (int i = 0; i < size; i++) {
    if (maxData < abs(arr[i])) {
      maxData = abs(arr[i]);
    }
  }

  int len = to_string(maxData).size();  // 获取最大数字的长度

  vector<vector<int>> vecs;   // 模拟桶

  int mod = 10;
  int dev = 1;


  for (int i = 0; i < len; mod *= 10, dev *= 10, i++) {
    vecs.resize(20);  // 初始化桶为20, 为了能处理负数。0-9号桶放负数,10-19号桶放正数

    for (int j = 0; j < size; j++) {
      // 得到当前元素第i个位置的数字
      int index = arr[j] % mod / dev + 10;  // 防止负数,加了10
      vecs[index].push_back(arr[j]);  // 将数字放到对应的桶中去
    }

    // 依次遍历所有的桶,把元素拷贝回原始的数组当中
    int idx = 0;
    for (auto vec: vecs) {
      for (int v: vec) {
        arr[idx++] = v;
      }
    }

    vecs.clear(); // 进行下一轮之前清空vector
  }
}

int main() {

  int arr[10];
  srand(time(nullptr));

  for (int i = 0; i < 10; i++) {
    arr[i] = rand() % 100 + 1;
  }

  arr[6] = -89;  // 负数
  arr[2] = -34;

  for (int v : arr) {
    cout << v << " ";
  }

  cout << endl;

  RadixSort(arr, 10);

  for (int v : arr) {
    cout << v << " ";
  }

  cout << endl;

  return 0;
}

测试

➜  build git:(radix) ✗ ./RadixSort    
52 17 -34 42 55 13 -89 63 56 52 
-89 -34 13 17 42 52 52 55 56 63