基数排序:独特的排序之道

news/2025/2/27 4:18:31

在排序算法的大家族中,基数排序凭借其独特的排序思路和应用场景,占据着不可或缺的位置。今天,就让我们一同深入探索基数排序的奥秘。

一、基数排序的核心思想

基数排序是一种非比较型整数排序算法,它的核心在于按位排序。与基于元素比较的排序算法不同,基数排序将整数按位数切割成不同的数字,然后从最低位开始,依次对每一位进行排序,直到最高位处理完毕,最终得到一个有序的数列。

举个简单的例子,假设有一组数字 [329, 457, 657, 839, 436, 720, 355]。首先,我们关注个位数字,将这些数字按照个位数字进行排序,得到 [720, 436, 355, 457, 657, 329, 839]。接着,对十位数字进行排序,结果变为 [720, 329, 436, 839, 355, 457, 657]。最后,按百位数字排序,得到最终的有序序列 [329, 355, 436, 457, 657, 720, 839]。每一位的排序就像是一场筛选,逐步将所有数字排列整齐。

二、基数排序的实现步骤

  1. 确定排序的位数:首先要找出待排序数组中最大的数,从而确定需要排序的最大位数。比如上述例子中最大数是 839,所以最大位数是 3 位。
  2. 从最低位开始排序:使用一种稳定的排序算法(如计数排序)对每一位进行排序。以计数排序为例,创建一个计数数组,统计每个数字在当前位上出现的次数,然后根据计数数组重新排列原数组中的元素。
  3. 重复步骤:依次对每一位进行排序,直到最高位完成排序,此时整个数组就有序了。

下面是使用 Java 实现基数排序的代码示例:

public class RadixSort {
    public static void radixSort(int[] arr) {
        // 找到最大数,确定最大位数
        int max = arr[0];
        for (int num : arr) {
            if (num > max) {
                max = num;
            }
        }

        // 从个位开始,对每一位进行排序
        for (int exp = 1; max / exp > 0; exp *= 10) {
            countSort(arr, exp);
        }
    }

    private static void countSort(int[] arr, int exp) {
        int[] output = new int[arr.length];
        int[] count = new int[10];

        // 统计每个数字在当前位上出现的次数
        for (int num : arr) {
            count[(num / exp) % 10]++;
        }

        // 计算累计计数,确定每个数字在输出数组中的位置
        for (int i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }

        // 根据计数数组,将原数组中的元素放入输出数组
        for (int i = arr.length - 1; i >= 0; i--) {
            output[count[(arr[i] / exp) % 10] - 1] = arr[i];
            count[(arr[i] / exp) % 10]--;
        }

        // 将输出数组复制回原数组
        System.arraycopy(output, 0, arr, 0, arr.length);
    }

    public static void main(String[] args) {
        int[] arr = {329, 457, 657, 839, 436, 720, 355};
        System.out.println("排序前数组: " + java.util.Arrays.toString(arr));
        radixSort(arr);
        System.out.println("排序后数组: " + java.util.Arrays.toString(arr));
    }
}

三、基数排序的时间和空间复杂度

  • 时间复杂度:基数排序的时间复杂度为 O(d(n + k)),其中 d 是最大数字的位数,n 是数列元素个数,k 是每一位的取值范围(如十进制中 k =10)。当数字位数 d 和取值范围 k 相对稳定时,基数排序的时间复杂度接近线性,在处理大规模数据时表现出色。
  • 空间复杂度:基数排序需要额外的空间来存储临时数据,如计数数组和输出数组,所以空间复杂度为 O(n + k) 。

四、基数排序的稳定性

基数排序是稳定的排序算法。在每一位的排序过程中,使用的稳定排序算法(如计数排序)确保了相等元素的相对顺序不会改变。这使得基数排序在一些对元素相对顺序有要求的场景中具有优势,比如在对学生成绩进行排序时,成绩相同的学生希望保持原来的顺序。

五、基数排序的应用场景

  1. 整数排序:由于基数排序针对整数按位排序的特性,非常适合对整数数组进行排序,尤其是在数字范围不是特别大且位数相对固定的情况下,效率极高。
  2. 字符串排序:通过将字符串看作字符的序列,也可以应用基数排序的思想进行排序。比如对一系列长度相同的单词按照字典序排序,就可以从字符串的最后一个字符开始,逐位进行排序。

六、总结

基数排序以其独特的按位排序方式,为我们提供了一种高效的排序解决方案。它在时间复杂度和稳定性方面的特点,使其在特定场景下能够发挥出巨大的优势。与其他排序算法相比,基数排序的思想独树一帜,为我们解决排序问题提供了新的思路。在实际应用中,我们可以根据数据的特点和需求,灵活选择合适的排序算法,让程序的性能得到最优发挥。


http://www.niftyadmin.cn/n/5869438.html

相关文章

8.Dashboard的导入导出

分享自己的Dashboard 1. 在Dashboard settings中选择 JSON Model 2. 导入 后续请参考第三篇导入光放Dashboard&#xff0c;相近

CSS 真的会阻塞文档解析吗?

在网页开发领域&#xff0c;一个常见的疑问是 CSS 是否会阻塞文档解析。理解这一问题对于优化网页性能、提升用户体验至关重要。要深入解答这个问题&#xff0c;需要从浏览器渲染网页的原理说起。 浏览器渲染网页的基本流程 浏览器在接收到 HTML 文档后&#xff0c;会依次进行…

Android 12系统源码_多屏幕(四)自由窗口模式

一、小窗模式 1.1 小窗功能的开启方式 开发者模式下开启小窗功能 adb 手动开启 adb shell settings put global enable_freeform_support 1 adb shell settings put global force_resizable_activities 11.2 源码配置 copy file # add for freedom PRODUCT_COPY_FILES …

直角三角堰计算公式

直角三角堰的计算公式通常用于确定流经直角三角形形状的堰的流量。河北瑾航科技遥测终端机 通过采集液位数据(模拟量、串口485/232)&#xff0c;计算得到瞬时流量&#xff0c;然后通过积分进行累计算出累积量&#xff1b;直角三角堰的流量计算公式为&#xff1a; 直角三角堰 计…

Windows程序设计28:MFC模态与非模态对话框

文章目录 前言一、创建模态对话框1.创建模态对话框模板2.绑定自定义对话框类3.创建模态对话框DoModal4.销毁模态对话框二、创建非模态对话框1.创建对话框模板2.绑定自定义对话框类3.创建非模态对话框Create、ShowWindow4.销毁非模态对话框5.销毁自身窗口指针总结前言 Windows程…

XTOM工业级蓝光三维扫描仪在笔记本电脑背板模具全尺寸检测中的高效精准应用

——某3C精密制造企业模具优化与质量管控案例 镁合金具有密度小、强度高、耐腐蚀性好等优点&#xff0c;成为笔记本电脑外壳主流材料。冲压模具作为批量生产笔记本电脑镁合金背板的核心工具&#xff0c;其精度直接决定了产品的尺寸一致性、结构可靠性与外观品质。微米级模具误…

MySQL数据库的基本命令

1.use mysql;切换***数据库 2.show databases&#xff1b;语句查看当前系统存在的数据库 其中的4个数据库都属于系统数据库&#xff0c; informain_schema:储存系统中一些数据库对象信息 mysql:主要 performance_schema: sys: 3.show tables;查看当前数据库中的表 4.sele…

记录一下用docker克隆某授权制定ip的环境恢复

#首先还是要看日志根据问题去进行调整 java web的老项目配置文件一般是 bin启动里边的脚本 还有conf中的 xml配置文件 再或者就是classes中的配置文件,再或者就是lib中的jar包中的配置文件 1.安装docker 2.创建docker网络 docker network create --driver bridge --subnet…