基数排序详解(LSD方法+MSD方法+思路+图解+代码)

news2024/11/17 15:48:58

文章目录

  • 基数排序
    • 一、基数排序
      • 概念
      • 1.LSD排序法(最低位优先法)
      • 2.MSD排序法(最高位优先法)


基数排序


一、基数排序

概念

  • 基数排序是一种非比较型整数排序算法

  • 将整数按位数切割成不同的数字,然后按每个位数分别比较

  • 使用场景:按位分割进行排序,适用于大数据范围排序,打破了计数排序的限制

  • 稳定性:稳定

  • 按位分割技巧:arr[i] / digit % 10,其中digit为10^n。

在这里插入图片描述

1.LSD排序法(最低位优先法)

  • 从最低位向最高位依次按位进行计数排序。

  • 进出的次数和最大值的位数有关

  • 桶可以用队列来表示

  • 数组的每个元素都是队列

在这里插入图片描述

  • 1.先遍历找到最大值
  • 2.求出最高位

在这里插入图片描述

    public static void radixSortR(int[] array) {
        //10进制数,有10个桶,每个桶最多存array.length个数
        int[][] bucket = new int[10][array.length];
        //桶里面要存的具体数值

        int[] bucketElementCounts = new int[10];
        //用来计算,统计每个桶所存的元素的个数,每个桶对应一个元素

        //1.求出最大数
        int MAX = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > MAX) {
                MAX = array[i];
            }
        }
        //求最大值的位数,先变成字符串,求字符串长度
        int MAXCount = (MAX + "").length();
        //最大位数的个数,进行几次计数排序
        for (int i = 0; i < MAXCount; i++) {//i代表第几次排序
            //放进桶中
            for (int k = 0; k < array.length; k++) {
                //k相当于遍历待排数值
                //array[k] /(int) Math.pow(10, i)%10 求出每次要比较位的数
                //求的是个位,并且是对应趟数的个位
                int value = (array[k] / (int) Math.pow(10, i)) % 10;
                //根据求出的位数,找到对应桶,放到对应桶的位置
                bucket[value][bucketElementCounts[value]] = array[k];
                //不管value 为多少,bucketElementCounts[value]的值都为0
                //相当于存到对应桶的0位bucket[value][0]
                bucketElementCounts[value]++; //从0->1
                //对应桶的技术数组开始计数
            }

            //取出每个桶中的元素,赋值给数组
            int index = 0;//array新的下标
            for (int k = 0; k < bucketElementCounts.length; k++) {//遍历每个桶
                if (bucketElementCounts[k] != 0) {//桶里有元素
                    for (int j = 0; j < bucketElementCounts[k]; j++) {//比那里每个桶的元素
                        array[index] = bucket[k][j];
                        index++;
                    }
                }
                bucketElementCounts[k] =0;//每个桶遍历完后,清空每个桶的元素;
            }
        }
    }

2.MSD排序法(最高位优先法)

在这里插入图片描述

  • 从最高位向最低位依次按位进行排序。
  • 按位递归分组收集
  • 1.查询最大值,获取最高位的基数
  • 2.按位分组,存入桶中
  • 3.组内元素数量>1,下一位递归分组
  • 4.组内元素数量=1.收集元素
   /**
     * 基数排序--MSD--递归
     * @param array
     */

    public static void radixSortMSD(int[] array) {
        //1.求出最大数
        int MAX = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > MAX) {
                MAX = array[i];
            }
        }
        //求最大值的位数,先变成字符串,求字符串长度
        int MAXCount = (MAX + "").length();
        // 计算最大值的基数
        int radix = new Double(Math.pow(10, MAXCount - 1)).intValue();

        int[] arr = msdSort(array, radix);
        System.out.println(Arrays.toString(arr));
    }
    public static int[] msdSort(int[] arr, int radix){
        // 递归分组到个位,退出
        if (radix <= 0) {
            return arr;
        }
        // 分组计数器
        int[] groupCounter = new int[10];

        // 分组桶
        int[][] groupBucket = new int[10][arr.length];

        for (int i = 0; i < arr.length; i++) {
            // 找分组桶位置
            int position = arr[i] / radix % 10;
            // 将元素存入分组
            groupBucket[position][groupCounter[position]] = arr[i];
            // 当前分组计数加1
            groupCounter[position]++;
        }

        int index = 0;
        int[] sortArr = new int[arr.length];


        // 遍历分组计数器
        for (int i = 0; i < groupCounter.length; i++) {
            // 组内元素数量>1,递归分组
            if (groupCounter[i] > 1) {
                int[] copyArr = Arrays.copyOf(groupBucket[i], groupCounter[i]);
                // 递归分组
                int[] tmp = msdSort(copyArr, radix / 10);
                // 收集递归分组后的元素
                for (int j = 0; j < tmp.length; j++) {
                    sortArr[index++] = tmp[j];
                }
            } else if (groupCounter[i] == 1) {
                // 收集组内元素数量=1的元素
                sortArr[index++] = groupBucket[i][0];
            }
        }
        return sortArr;
    }

点击移步博客主页,欢迎光临~

偷cyk的图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1235249.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ArcGIS教程——ArcGIS工具-按线分割面

功能说明 在ArcGIS数据处理过程中&#xff0c;有时需要沿线把面要素分割开&#xff0c;可以使用高级编辑中的分割面&#xff08;Cut Polygon&#xff09;工具。那么&#xff0c;如果要用线图层分割面图层该怎么办呢&#xff1f;地理遥感生态网平台开发了一个自定义模型工具。它…

工业交换机的六种分类

工业交换机可以按照不同的标准进行分类&#xff0c;具体有六种分类方法。我们今天就来简单了解一下这六种分类方法&#xff0c;它们分别是&#xff1a;工业交换机的管理标准、工业交换机的结构标准、工业交换机的网络位置、工业交换机的传输速率、工业交换机的工作协议以及工业…

MySQL索引,你真的学会了?索引底层原理是什么?索引什么时候失效,你知道吗?

目录 1、什么是索引 2、索引分类 3、索引的基本操作 3.1、主键索引 3.2、单列索引 3.3、唯一索引 3.4、复合索引 4、索引的底层原理 为什么使用BTree而不是B-Tree? 如果数据量特别大的情况下&#xff0c;BTree会不会深度太深影响查询效率&#xff1f; 5、聚簇索引和…

【Linux系统化学习】进程优先级 | 进程饥饿 | 进程切换

个人主页点击直达&#xff1a;小白不是程序媛 Linux专栏&#xff1a;Linux系统化学习 目录 进程优先级 什么是优先级&#xff1f; 为什么会有优先级&#xff1f; 如何做到的&#xff1f; 优先级的动态调整 查看进程优先级的命令 PRI 和 NI PRI VS NI 修改进程优先级 …

https想访问本地部署的http://localhost接口

情况说明&#xff1a; 网址是https的&#xff0c;想访问java本地启的一个程序接口http://localhost:8089 解决办法 java程序加上

flutter vscode gradle 配置

我这边主要改了如图两个文件&#xff0c;然后把Gradle的问题解决了 参考文章&#xff1a; flutter运行Runt imeException: Timeout of 120000问题-CSDN博客 flutter配置gradle&#xff08;个人笔记&#xff0c;非教程&#xff09;_flutter gradle_追寻着星星的方向的博客-CSD…

本机idea连接虚拟机中的Hbase

相关环境&#xff1a; 虚拟机&#xff1a;Centos7 hadoop版本:3.1.3 hbase版本:2.4.11 zookeeper版本:3.5.7 Java IDE:IDEA JDK&#xff1a;8 步骤 步骤一&#xff1a;在idea创建一个maven项目 步骤二&#xff1a;在虚拟机里找到core-site.x…

FreeRTOS内存管理分析

目录 heap_1.c内存管理算法 heap_2.c内存管理算法 heap_3.c内存管理算法 heap_4.c内存管理算法 heap_5.c内存管理算法 内存管理对应用程序和操作系统来说非常重要&#xff0c;而内存对于嵌入式系统来说是寸土寸金的资源&#xff0c;FreeRTOS操作系统将内核与内存管理分开实…

腾讯云HAI域AI作画

目录 &#x1f433;前言&#xff1a; &#x1f680;了解高性能应用服务 HAI &#x1f47b;即插即用 轻松上手 &#x1f47b;横向对比 青出于蓝 &#x1f424;应用场景-AI作画 &#x1f424;应用场景-AI对话 &#x1f424;应用场景-算法研发 &#x1f680;使用HAI进行…

Decoder-Only、Encoder-Only和Encoder-Decoder架构的模型区别、优缺点以及使用其架构的模型示例

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

YOLO改进系列之注意力机制(GatherExcite模型介绍)

模型结构 尽管在卷积神经网络&#xff08;CNN&#xff09;中使用自底向上的局部运算符可以很好地匹配自然图像的某些统计信息&#xff0c;但它也可能阻止此类模型捕获上下文的远程特征交互。Hu等人提出了一种简单&#xff0c;轻量级的方法&#xff0c;以在CNN中更好地利用上下…

Flowable工作流基础篇

文章目录 一、Flowable介绍二、Flowable基础1.创建ProcessEngine2.部署流程定义3.启动流程实例4.查看任务5.完成任务6.流程的删除7.查看历史信息 三、Flowable流程设计器1.Eclipse Designer1.1 下载安装Eclipse1.2 安装Flowable插件1.3 创建项目1.4 创建流程图1.5 部署流程 2.F…

VMware——WindowServer2012R2环境安装mysql5.7.14解压版_主从复制(图解版)

目录 一、服务器信息二、192.168.132.33主服务器上安装mysql&#xff08;主&#xff09;2.1、环境变量配置2.2、安装2.2.1、修改配置文件内容2.2.2、初始化mysql并指定超级用户密码2.2.3、安装mysql服务2.2.4、启动mysql服务2.2.5、登录用户管理及密码修改2.2.6、开启远程访问 …

【每日一题】设计循环队列(C语言)

循环队列是我们可以对队列有更深一步的理解的题目&#xff0c;而且可以进一步加强其他方面的知识&#xff08;例如对循环数组的取模运算&#xff0c;指针的解引用&#xff09;&#xff0c;是个蛮不错的巩固习题&#xff0c;话不多说&#xff0c;进入正题。 链接在此&#xff1…

事件溯源(Event Sourcing)和命令查询责任分离(CQRS)经验

这篇文章是实现一个基于 CQRS 和事件溯源原则的应用程序&#xff0c;描述这个过程的方式&#xff0c;我相信分享我面临的挑战和问题可能对一些人有用。特别是如果你正在开始自己的旅程。 业务背景 项目的背景与空中交通管理&#xff08;ATM&#xff09;领域相关。我们为一个 …

14. UART串口通信

14. UART串口通信 1. UART1.1 UART 通信格式1.2 UART 电平标准1.3 I.MX6U UART 简介1.3.1 控制寄存器1 UARTx_UCR1(x1~8)1.3.2 控制寄存器2 UARTx_UCR21.3.3 控制寄存器3 UARTx_UCR31.3.4 状态寄存器2 UARTx_USR21.3.4 UARTx_UFCR 、 UARTx_UBIR 和 UARTx_UBMR1.3.5 UARTx_URXD…

IDEA-运行测试方法提示Command line is too long

使用IDEA版本 执行时提示 处理方法&#xff1a; 1&#xff0c; 2&#xff0c;

electron项目开机自启动

一、效果展示&#xff1a;界面控制是否需要开机自启动 二、代码实现&#xff1a; 1、在渲染进程login.html中&#xff0c;画好界面&#xff0c;默认勾选&#xff1b; <div class"intro">开机自启动 <input type"checkbox" id"checkbox&quo…

MySQL数据库系统教程

基础篇 通用语法及分类 DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用…

Window下如何对Redis进行开启与关闭

目录 前言1. 图文界面2. 命令行 前言 由于长期使用Linux界面&#xff0c;对于Window下的Redis&#xff0c;不知如何下手。特此记录该博文 特别注意&#xff0c;刚下载好的Redis&#xff0c;如果需要配置密码&#xff0c;可以再该文件进行配置&#xff1a;redis.windows-servi…