📜  基数排序算法

📅  最后修改于: 2020-09-28 02:46:32             🧑  作者: Mango

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

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

假设我们有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 

Python,Java和C / C++示例

Python
爪哇
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 cummulative 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

import java.util.Arrays;

class RadixSort {

  // Using counting sort to sort the elements in the basis of significant places
  void countingSort(int array[], int size, int place) {
    int[] output = new int[size + 1];
    int max = array[0];
    for (int i = 1; i < size; i++) {
      if (array[i] > max)
        max = array[i];
    }
    int[] count = new int[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];
  }

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

  // 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);
  }

  // Driver code
  public static void main(String args[]) {
    int[] data = { 121, 432, 564, 23, 1, 45, 788 };
    int size = data.length;
    RadixSort rs = new RadixSort();
    rs.radixSort(data, size);
    System.out.println("Sorted Array in Ascending Order: ");
    System.out.println(Arrays.toString(data));
  }
}
// Radix Sort in C Programming

#include 

// 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 
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)。
  • 大范围数字的地方。