原文: https://www.programiz.com/dsa/radix-sort

在本教程中,您将学习基数排序的工作原理。 此外,您还将找到 C,C++ ,Java 和 Python 中基数排序的工作示例。

基数排序是一种排序技术,它通过首先对相同位置值的各个数字进行分组来对元素进行排序。 然后,根据元素的升序/降序对元素进行排序。

假设我们有 8 个元素组成的数组。 首先,我们将基于单位位置的值对元素进行排序。 然后,我们将根据第十位的值对元素进行排序。 这个过程一直持续到最后一个重要位置。

令初始数组为[121, 432, 564, 23, 1, 45, 788]。 如下图所示,根据基数排序。

基数排序算法 - 图1

基数排序的原理

在阅读本文之前,请先阅读计数排序,因为计数排序用作基数排序的中间排序。


基数排序如何工作?

  1. 找到数组中最大的元素,即max。 令Xmax中的位数。 计算X是因为我们必须遍历所有元素的所有重要位置。
    在此数组[121, 432, 564, 23, 1, 45, 788]中,我们拥有最大的数字 788。它具有 3 位数字。 因此,循环应上升到百位(3 次)。

  2. 现在,一个接一个地访问每个重要的地方。
    使用任何稳定的排序技术在每个重要位置对数字进行排序。 我们为此使用了计数排序。
    根据单位位置数字(X=0)对元素进行排序。
    基数排序算法 - 图2
    使用计数排序对基于单位位置的元素进行排序

  3. 现在,基于十位数字对元素进行排序。
    基数排序算法 - 图3
    根据十位对元素进行排序

  4. 最后,根据百位数字对元素进行排序。
    基数排序算法 - 图4
    根据数百个位置对元素进行排序


基数排序算法

  1. radixSort(array)
  2. d <- maximum number of digits in the largest element
  3. create d buckets of size 0-9
  4. for i <- 0 to d
  5. sort the elements according to ith place digits using countingSort
  6. countingSort(array, d)
  7. max <- find largest element among dth place elements
  8. initialize count array with all zeros
  9. for j <- 0 to size
  10. find the total count of each unique digit in dth place of elements and
  11. store the count at jth index in count array
  12. for i <- 1 to max
  13. find the cumulative sum and store it in count array itself
  14. for j <- size down to 1
  15. restore the elements to array
  16. decrease count of each element restored by 1

Python,Java 和 C/C++ 示例

  1. # Radix sort in Python
  2. # Using counting sort to sort the elements in the basis of significant places
  3. def countingSort(array, place):
  4. size = len(array)
  5. output = [0] * size
  6. count = [0] * 10
  7. # Calculate count of elements
  8. for i in range(0, size):
  9. index = array[i] // place
  10. count[index % 10] += 1
  11. # Calculate cummulative count
  12. for i in range(1, 10):
  13. count[i] += count[i - 1]
  14. # Place the elements in sorted order
  15. i = size - 1
  16. while i >= 0:
  17. index = array[i] // place
  18. output[count[index % 10] - 1] = array[i]
  19. count[index % 10] -= 1
  20. i -= 1
  21. for i in range(0, size):
  22. array[i] = output[i]
  23. # Main function to implement radix sort
  24. def radixSort(array):
  25. # Get maximum element
  26. max_element = max(array)
  27. # Apply counting sort to sort elements based on place value.
  28. place = 1
  29. while max_element // place > 0:
  30. countingSort(array, place)
  31. place *= 10
  32. data = [121, 432, 564, 23, 1, 45, 788]
  33. radixSort(data)
  34. print(data)
  1. // Radix Sort in Java Programming
  2. import java.util.Arrays;
  3. class RadixSort {
  4. // Using counting sort to sort the elements in the basis of significant places
  5. void countingSort(int array[], int size, int place) {
  6. int[] output = new int[size + 1];
  7. int max = array[0];
  8. for (int i = 1; i < size; i++) {
  9. if (array[i] > max)
  10. max = array[i];
  11. }
  12. int[] count = new int[max + 1];
  13. for (int i = 0; i < max; ++i)
  14. count[i] = 0;
  15. // Calculate count of elements
  16. for (int i = 0; i < size; i++)
  17. count[(array[i] / place) % 10]++;
  18. // Calculate cummulative count
  19. for (int i = 1; i < 10; i++)
  20. count[i] += count[i - 1];
  21. // Place the elements in sorted order
  22. for (int i = size - 1; i >= 0; i--) {
  23. output[count[(array[i] / place) % 10] - 1] = array[i];
  24. count[(array[i] / place) % 10]--;
  25. }
  26. for (int i = 0; i < size; i++)
  27. array[i] = output[i];
  28. }
  29. // Function to get the largest element from an array
  30. int getMax(int array[], int n) {
  31. int max = array[0];
  32. for (int i = 1; i < n; i++)
  33. if (array[i] > max)
  34. max = array[i];
  35. return max;
  36. }
  37. // Main function to implement radix sort
  38. void radixSort(int array[], int size) {
  39. // Get maximum element
  40. int max = getMax(array, size);
  41. // Apply counting sort to sort elements based on place value.
  42. for (int place = 1; max / place > 0; place *= 10)
  43. countingSort(array, size, place);
  44. }
  45. // Driver code
  46. public static void main(String args[]) {
  47. int[] data = { 121, 432, 564, 23, 1, 45, 788 };
  48. int size = data.length;
  49. RadixSort rs = new RadixSort();
  50. rs.radixSort(data, size);
  51. System.out.println("Sorted Array in Ascending Order: ");
  52. System.out.println(Arrays.toString(data));
  53. }
  54. }
// Radix Sort in C Programming

#include <stdio.h>

// Function to get the largest element from an array
int getMax(int array[], int n) {
  int max = array[0];
  for (int i = 1; i < n; i++)
    if (array[i] > max)
      max = array[i];
  return max;
}

// Using counting sort to sort the elements in the basis of significant places
void countingSort(int array[], int size, int place) {
  int output[size + 1];
  int max = (array[0] / place) % 10;

  for (int i = 1; i < size; i++) {
    if (((array[i] / place) % 10) > max)
      max = array[i];
  }
  int count[max + 1];

  for (int i = 0; i < max; ++i)
    count[i] = 0;

  // Calculate count of elements
  for (int i = 0; i < size; i++)
    count[(array[i] / place) % 10]++;

  // Calculate cummulative count
  for (int i = 1; i < 10; i++)
    count[i] += count[i - 1];

  // Place the elements in sorted order
  for (int i = size - 1; i >= 0; i--) {
    output[count[(array[i] / place) % 10] - 1] = array[i];
    count[(array[i] / place) % 10]--;
  }

  for (int i = 0; i < size; i++)
    array[i] = output[i];
}

// Main function to implement radix sort
void radixsort(int array[], int size) {
  // Get maximum element
  int max = getMax(array, size);

  // Apply counting sort to sort elements based on place value.
  for (int place = 1; max / place > 0; place *= 10)
    countingSort(array, size, place);
}

// Print an array
void printArray(int array[], int size) {
  for (int i = 0; i < size; ++i) {
    printf("%d  ", array[i]);
  }
  printf("\n");
}

// Driver code
int main() {
  int array[] = {121, 432, 564, 23, 1, 45, 788};
  int n = sizeof(array) / sizeof(array[0]);
  radixsort(array, n);
  printArray(array, n);
}
// Radix Sort in C++ Programming

#include <iostream>
using namespace std;

// Function to get the largest element from an array
int getMax(int array[], int n) {
  int max = array[0];
  for (int i = 1; i < n; i++)
    if (array[i] > max)
      max = array[i];
  return max;
}

// Using counting sort to sort the elements in the basis of significant places
void countingSort(int array[], int size, int place) {
  const int max = 10;
  int output[size];
  int count[max];

  for (int i = 0; i < max; ++i)
    count[i] = 0;

  // Calculate count of elements
  for (int i = 0; i < size; i++)
    count[(array[i] / place) % 10]++;

  // Calculate cummulative count
  for (int i = 1; i < max; i++)
    count[i] += count[i - 1];

  // Place the elements in sorted order
  for (int i = size - 1; i >= 0; i--) {
    output[count[(array[i] / place) % 10] - 1] = array[i];
    count[(array[i] / place) % 10]--;
  }

  for (int i = 0; i < size; i++)
    array[i] = output[i];
}

// Main function to implement radix sort
void radixsort(int array[], int size) {
  // Get maximum element
  int max = getMax(array, size);

  // Apply counting sort to sort elements based on place value.
  for (int place = 1; max / place > 0; place *= 10)
    countingSort(array, size, place);
}

// Print an array
void printArray(int array[], int size) {
  int i;
  for (i = 0; i < size; i++)
    cout << array[i] << " ";
  cout << endl;
}

// Driver code
int main() {
  int array[] = {121, 432, 564, 23, 1, 45, 788};
  int n = sizeof(array) / sizeof(array[0]);
  radixsort(array, n);
  printArray(array, n);
}

复杂度

由于基数排序是一种非比较算法,因此它比比较排序算法具有优势。

对于使用计数排序作为中间稳定排序的基数排序,时间复杂度为O(d(n+k))

此处,d是数字循环,O(n+k)是计数排序的时间复杂度。

因此,基数排序具有线性时间复杂度,该复杂度优于比较排序算法的O(nlog n)

如果我们使用非常大的数字或其他基数(例如 32 位和 64 位数字),那么它可以在线性时间内执行,但是中间排序会占用很大的空间。

这使得基数排序空间效率低下。 这就是为什么在软件库中不使用这种排序的原因。


基数排序应用

基数排序在

  • 制作后缀数组时使用 DC3 算法(Kärkkäinen-Sanders-Burkhardt)。
  • 大范围数字的地方。