排序算法---基数排序

原创不易,转载请注明出处。欢迎点赞收藏~

基数排序是一种非比较型的排序算法,用于对整数进行排序。它将整数按照位数进行分组,从低位到高位依次进行排序,最终得到有序序列。

算法步骤如下:

  1. 找到待排序序列中的最大值,确定需要进行多少轮排序。
  2. 根据最大值的位数,从低位到高位依次进行排序。
  3. 对于每一位进行排序,可以使用稳定的计数排序或桶排序来实现。
  4. 按照每一位的排序结果进行重组,得到新的序列。
  5. 重复步骤3和4,直到最高位排序完成。

时间复杂度:

  • 对于n个d位数的排序,每一位的排序需要O(n)的时间复杂度,共需进行d轮排序,因此总的时间复杂度为O(d*n)。
  • 如果d是常数,那么时间复杂度可以简化为O(n)。

空间复杂度:

  • 由于基数排序需要额外的存储空间来存储中间结果和临时数组,空间复杂度为O(n+k),其中k取决于桶的大小。

基数排序的优点是稳定性高,适用于对大量数据进行排序,尤其是数据位数相同的情况。缺点是对于负数的排序不直接适用,并且需要额外的存储空间。

以下是一个基数排序的C语言示例代码:

cpp 复制代码
#include <stdio.h>

// 获取数组中最大的元素
int get_max(int arr[], int n)
{
    int max = arr[0];
    for (int i = 1; i < n; i++)
    {
        if (arr[i] > max)
        {
            max = arr[i];
        }
    }
    return max;
}

// 使用计数排序对数组进行排序(根据某个位数)
void counting_sort(int arr[], int n, int exp)
{
    int output[n];       // 存储临时结果的数组
    int count[10] = {0}; // 用于计数的数组

    // 统计元素出现的次数
    for (int i = 0; i < n; i++)
    {
        count[(arr[i] / exp) % 10]++;
    }

    // 将count数组更新为每个元素的累加和
    for (int i = 1; i < 10; i++)
    {
        count[i] += count[i - 1];
    }

    // 根据count数组的值,将元素放到output数组中
    for (int i = n - 1; i >= 0; i--)
    {
        output[count[(arr[i] / exp) % 10] - 1] = arr[i];
        count[(arr[i] / exp) % 10]--;
    }

    // 将output数组复制回arr数组
    for (int i = 0; i < n; i++)
    {
        arr[i] = output[i];
    }
}

// 实现基数排序函数
void radix_sort(int arr[], int n)
{
    // 获取数组中最大元素
    int max = get_max(arr, n);

    // 根据位数进行计数排序
    for (int exp = 1; max / exp > 0; exp *= 10)
    {
        counting_sort(arr, n, exp);
    }
}

// 测试基数排序算法
int main()
{
    int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("排序前的数组:\n");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }

    radix_sort(arr, n);

    printf("\n排序后的数组:\n");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }
    putchar('\n');

    return 0;
}

以上代码演示了基数排序的实现过程。基数排序是一种非比较性的排序算法,它根据排序元素的位数依次将元素进行桶排序,实现对整个数组的排序。

代码中的 get_max() 函数用于获取数组中的最大元素,这是为了确定需要进行多少轮排序(根据最大元素的位数确定)。

counting_sort() 函数是基数排序中使用的辅助函数,它基于某个位数对数组进行计数排序。首先创建一个临时数组 output 用于存储排序结果,创建一个计数数组 count,初始化为全零。然后,遍历数组并根据当前位数将元素计数加一。接下来,将 count 数组更新为每个元素的累加和,这样 count 数组的值就表示小于等于当前数字的元素个数。最后,根据 count 数组的值,将元素放到 output 数组中,并更新 count 数组的值。最后,将 output 数组复制回原数组。

radix_sort() 函数是实现基数排序的主要函数。它通过迭代不同位数进行计数排序,直到排完最高位数为止。

main() 函数中,我们定义了一个测试数组 arr,然后调用 radix_sort() 函数对其进行排序,并输出排序后的结果。

运行如上代码,你可以看到以下输出:

相关推荐
小羊没烦恼!28 分钟前
Memory 记忆设计讨论:为什么 Agent Memory 不能只靠向量数据库?
java·开发语言·windows·算法·c#
ysu_03141 小时前
08-二叉树遍历:四种方式详解
c语言·数据结构·算法·leetcode
咸鱼老弟1 小时前
Speculative Decoding(投机采样):大模型"先猜后验",生成速度翻倍
前端·算法·ai编程
荆棘鸟智能1 小时前
AI算法持续学习与迭代怎么做?从数据闭环到灰度发布的MLOps工程实践
人工智能·算法·架构·边缘计算
Lyyaoo.1 小时前
【二分查找】【中等】搜索二维矩阵/排序数组的第一位和最后位置/搜索旋转排序数组/旋转排序数组中的最小值
java·数据结构·算法
土司大王2 小时前
LeetCode hot100——153.寻找旋转排序数组中的最小值:Java 二分模板与 O(log n) 分析
java·算法·leetcode
光电的一只菜鸡2 小时前
isp中关于锐化对图像清晰度的影响
算法
土司大王2 小时前
LeetCode hot100——4.寻找两个正序数组的中位数:Java 二分第K小 递归裁剪
java·算法·leetcode
薛定e的猫咪2 小时前
(ICML2024)QSM:基于 Q 函数梯度对齐分数场的扩散模型离策略强化学习
人工智能·深度学习·算法
hetao17338372 小时前
2026-09-13 hetao1733837 的刷题记录
c++·算法