基数排序算法

基数排序是一种排序算法,它首先根据相同位值的单个数字对元素进行分组,然后根据这些元素的升序/降序对其进行排序。

假设我们有一个包含 8 个元素的数组。首先,我们将根据个位值对元素进行排序。然后,我们将根据十位值对元素进行排序。这个过程将一直持续到最后一个有效位。

设初始数组为 [121, 432, 564, 23, 1, 45, 788]。如下图所示,它通过基数排序进行排序。

Radix Sort Working
基数排序的工作原理

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


基数排序的工作原理

  1. 找到数组中的最大元素,即 max。设 Xmax 中的数字位数。计算 X 是因为我们需要遍历所有元素的有效位。

    在这个数组 [121, 432, 564, 23, 1, 45, 788] 中,最大数字是 788。它有 3 位数。因此,循环应持续到百位(3 次)。
  2. 现在,逐一遍历每个有效位。

    使用任何稳定的排序技术对每个有效位的数字进行排序。我们在这里使用了计数排序。

    根据个位数字(X=0)对元素进行排序。
    Radix Sort working with Counting Sort as intermediate step
    使用计数排序根据个位对元素进行排序
  3. 现在,根据十位数字对元素进行排序。
    Radix Sort Step
    根据十位对元素进行排序
  4. 最后,根据百位数字对元素进行排序。
    Selection Sort Step
    根据百位对元素进行排序

基数排序算法

radixSort(array)
  d <- maximum number of digits in the largest element
  create d buckets of size 0-9
  for i <- 0 to d
    sort the elements according to ith place digits using countingSort

countingSort(array, d)
  max <- find largest element among dth place elements
  initialize count array with all zeros
  for j <- 0 to size
    find the total count of each unique digit in dth place of elements and
    store the count at jth index in count array
  for i <- 1 to max
    find the cumulative sum and store it in count array itself
  for j <- size down to 1
    restore the elements to array
    decrease count of each element restored by 1

Python、Java 和 C/C++ 中的基数排序代码

# Radix sort in Python
# Using counting sort to sort the elements in the basis of significant places
def countingSort(array, place):
    size = len(array)
    output = [0] * size
    count = [0] * 10

    # Calculate count of elements
    for i in range(0, size):
        index = array[i] // place
        count[index % 10] += 1

    # Calculate cumulative count
    for i in range(1, 10):
        count[i] += count[i - 1]

    # Place the elements in sorted order
    i = size - 1
    while i >= 0:
        index = array[i] // place
        output[count[index % 10] - 1] = array[i]
        count[index % 10] -= 1
        i -= 1

    for i in range(0, size):
        array[i] = output[i]


# Main function to implement radix sort
def radixSort(array):
    # Get maximum element
    max_element = max(array)

    # Apply counting sort to sort elements based on place value.
    place = 1
    while max_element // place > 0:
        countingSort(array, place)
        place *= 10


data = [121, 432, 564, 23, 1, 45, 788]
radixSort(data)
print(data)
// Radix Sort in Java Programming
public class RadixSort {
    // Using counting sort to sort the elements based on significant places
    public static void countingSort(int[] array, int place) {
        int size = array.length;
        int[] output = new int[size];
        int[] count = new int[10];
        
        // Calculate count of elements
        for (int i = 0; i < size; i++) {
            int index = (array[i] / place) % 10;
            count[index]++;
        }
        // Calculate cumulative 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--) {
            int index = (array[i] / place) % 10;
            output[count[index] - 1] = array[i];
            count[index]--;
        }
        // Copy the sorted elements into original array
        for (int i = 0; i < size; i++) {
            array[i] = output[i];
        }
    }
    // Main function to implement radix sort
    public static void radixSort(int[] array) {
        // Get maximum element
        int maxElement = getMax(array);
        // Apply counting sort to sort elements based on place value
        for (int place = 1; maxElement / place > 0; place *= 10) {
            countingSort(array, place);
        }
    }
    // A utility function to get the maximum value in the array
    public static int getMax(int[] array) {
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        return max;
    }
    public static void main(String[] args) {
        int[] data = {121, 432, 564, 23, 1, 45, 788};
        radixSort(data);
        System.out.println("Sorted Array in Ascending Order: ");
        for (int num : data) {
            System.out.print(num + " ");
        }
    }
}
// Radix Sort in C Programming
#include <stdio.h>
// Function to get the maximum value in the 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 based on significant places
void countingSort(int array[], int n, int place) {
    int output[n];
    int count[10] = {0};
    // Calculate count of elements
    for (int i = 0; i < n; i++) {
        int index = (array[i] / place) % 10;
        count[index]++;
    }
    // Calculate cumulative count
    for (int i = 1; i < 10; i++) {
        count[i] += count[i - 1];
    }
    // Place the elements in sorted order
    for (int i = n - 1; i >= 0; i--) {
        int index = (array[i] / place) % 10;
        output[count[index] - 1] = array[i];
        count[index]--;
    }
    // Copy the sorted elements into original array
    for (int i = 0; i < n; i++) {
        array[i] = output[i];
    }
}
// Main function to implement radix sort
void radixSort(int array[], int n) {
    // Get maximum element
    int maxElement = getMax(array, n);
    // Apply counting sort to sort elements based on place value
    for (int place = 1; maxElement / place > 0; place *= 10) {
        countingSort(array, n, place);
    }
}
int main() {
    int data[] = {121, 432, 564, 23, 1, 45, 788};
    int n = sizeof(data) / sizeof(data[0]);
    radixSort(data, n);
    printf("Sorted array in ascending order:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", data[i]);
    }
    return 0;
}

// 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 cumulative 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(n+k)
最坏 O(n+k)
平均 O(n+k)
空间复杂度 O(max)
稳定性

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

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

其中,d 是循环次数,O(n+k) 是计数排序的时间复杂度。

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

如果我们处理非常大的数字或具有不同基数的数字,例如 32 位和 64 位数字,它可以以线性时间运行,但中间排序会占用大量空间。

这使得基数排序在空间方面效率低下。这就是为什么此排序未在软件库中使用。


基数排序的应用

基数排序在以下方面有应用:

  • DC3 算法(Kärkkäinen-Sanders-Burkhardt)在构建后缀数组时。
  • 数字范围很大的地方。

类似的排序算法

  1. 快速排序
  2. 归并排序
  3. 桶排序
  4. 计数排序
你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战