5-3 其他排序:基数排序

基数排序

基数排序是一种线性排序算法(适用于固定长度的数字计数),它逐位处理元素进行排序。对于键长固定的整数或字符串,它是一种高效的排序算法。

  • 它会根据每个数字的值,反复地将元素分配到不同的桶中。这与其他算法(例如归并排序或快速排序)不同,后者是直接比较元素的。
  • 通过反复按有效数字对元素进行排序,从最低有效位到最高有效位,即可得到最终的排序结果。
  • 我们使用像计数排序这样的稳定​​算法来对各个数字进行排序,以保持整个算法的稳定性。

要对数组 [170, 45, 75, 90, 802, 24, 2, 66] 执行基数排序,我们遵循以下步骤:
步骤 1:找到最大元素,即 802。它有三位数,所以我们将迭代三次。
步骤 2:根据个位数字对元素进行排序(X=0)。
image
步骤 3:按十位数字对元素进行排序。
image
步骤 4:按百位数字对元素进行排序。
image
步骤 5:数组现在已按升序排序。
image


代码实现

// C++ implementation of Radix Sort

#include <iostream>

// A utility function to get maximum
// value in arr[]
int getMax(int arr[], int n)
{
    int mx = arr[0];
    for (int i = 1; i < n; i++)
    {
        if (arr[i] > mx)
        {
            mx = arr[i];
        }
    }
    return mx;
}

// A function to do counting sort of arr[]
// according to the digit
// represented by exp.
void countSort(int arr[], int n, int exp)
{
    // Output array
    int output[n];
    int i, count[10] = { 0 };

    // Store count of occurrences
    // in count[]
    for (i = 0; i < n; i++)
    {
        count[(arr[i] / exp) % 10]++;
    }

    // Change count[i] so that count[i]
    // now contains actual position
    // of this digit in output[]
    for (i = 1; i < 10; i++)
    {
        count[i] += count[i - 1];
    }

    // Build the output array
    for (i = n - 1; i >= 0; i--)
    {
        output[count[(arr[i] / exp) % 10] - 1] = arr[i];
        count[(arr[i] / exp) % 10]--;
    }

    // Copy the output array to arr[],
    // so that arr[] now contains sorted
    // numbers according to current digit
    for (i = 0; i < n; i++)
    {
        arr[i] = output[i];
    }
}

// The main function to that sorts arr[]
// of size n using Radix Sort
void radixsort(int arr[], int n)
{
    // Find the maximum number to
    // know number of digits
    int m = getMax(arr, n);

    // Do counting sort for every digit.
    // Note that instead of passing digit
    // number, exp is passed. exp is 10^i
    // where i is current digit number
    for (int exp = 1; m / exp > 0; exp *= 10)
    {
        countSort(arr, n, exp);
    }
}

// A utility function to print an array
void print(int arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        std::cout << arr[i] << " ";
    }
}

// Driver Code
int main()
{
    int arr[] = { 170, 45, 75, 90, 802, 24, 2, 66 };
    int n = sizeof(arr) / sizeof(arr[0]);

    // Function Call
    radixsort(arr, n);
    print(arr, n);
    return 0;
}

输出:
image


基数排序的复杂度分析:

时间复杂度:

  • 基数排序是一种非比较整数排序算法,它通过将键值相同的数字分组,对具有整数键的数据进行排序。它的时间复杂度为O(d * (n + b)),其中 d 是数字位数,n 是元素个数,b 是所用进制的基数。
  • 在实际应用中,对于大型数据集,尤其是键值位数较多时,基数排序通常比其他基于比较的排序算法(例如快速排序或归并排序)更快。然而,它的时间复杂度随位数线性增长,因此对于小型数据集来说效率不高。

辅助空间:

  • 基数排序的空间复杂度为O(n + b),其中 n 是元素个数,b 是数制的基数。这种空间复杂度源于需要为每个数字值创建桶,并在每次排序后将元素复制回原始数组。
posted @ 2026-03-30 18:31  游翔  阅读(0)  评论(0)    收藏  举报