基数排序O(n)时间复杂度的实现

news2024/12/25 23:30:27

基数排序O(n)时间复杂度的实现

前言

之前写过一篇文章六种常见排序算法分析与实现,讲了六种常见的排序算法,但是没有了解到桶排序,基数排序这两种排序算法,今天刷LeetCode发现了这两种算法,本文先来聊聊基数排序的思想以及代码实现。

一、算法思想

基数排序它的思想很简单,难点在于如何实现这种思想。
基数排序又称为桶子法,算法思路就是对数字从低位到高位逐个完成排序,最终数据就有序了,其实,理解起来很简单,你每一位都排序了,那么最终整体也就有序了。参考视频:排序算法详解(七)基数排序

下面给出一个基数排序的示例过程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、算法实现

2.1 实现一

根据上面的算法思想,直观进行实现,定义10个桶,每个桶中装一个List列表,具体实现如下:

public static int[] radixSort(int[] nums) {
        int max = Arrays.stream(nums).max().getAsInt();
        //定义桶
        ArrayList<Integer>[] bucket = new ArrayList[10];
        //通过num/base,每次去除数字的最后一位
        int base = 1;
        //存储每次从桶中取出的数字
        int[] temp = new int[nums.length];
        while (max / base > 0) {
            //初始化桶
            for (int i = 0; i < 10; i++) {
                bucket[i] = new ArrayList<>();
            }
            //依次计算位数放入桶中
            for (int i = 0; i < nums.length; i++) {
                bucket[nums[i]/base % 10].add(nums[i]);
            }
            //取出桶中的数字
            int index = 0;
            for (ArrayList<Integer> list : bucket) {
                for (Integer value : list) {
                    temp[index++] = value;
                }
            }
            //将temp中的数字拷贝到nums
            System.arraycopy(temp,0,nums,0,temp.length);
            base*=10;
        }
        return nums;
    }

2.2 实现二

实现一更便于理解,但空间复杂度还有一定的优化空间,可以不用在桶中装List来降低空间复杂度,那么这种实现的核心点就在于如何把桶中的数据依次再拿出来赋值给原数组,即要确定每个数字从桶中拿出来后,应该放在数组的什么位置?而这个位置可以通过计算该桶前面一共有多少个数字来确定。
如上面的示例中,最后根据百位数把数字放进桶中后的结果如下:
在这里插入图片描述
那么678这个数字应该放在数组的什么位置?很明显,678前面还要放置5个数字,因此678应该放在第5+1=6的位置。

具体实现算法如下:

/**
     * 基数排序,(桶排序)
     * 算法思路:
     * 1. 获取最大数字,确定位数n
     * 2. 设置10个桶(0~9),存放每位的数字
     * 3. 遍历所有数字,如果数字的第n位是i,则放到第i个桶
     * 4. 将桶中的数字全部取出,重新放入nums数组
     * 5. 重复3,4步,n次,最后nums就是有序的数组了
     *
     * @param nums
     * @return
     */
    public static int[] radixSort(int[] nums) {
        int n = nums.length;
        int max = Arrays.stream(nums).max().getAsInt();
        //定义10个桶
        int[] bucket;
        //用于临时存储每次从桶中拿出的数据
        int[] temp = new int[n];
        int rate = 1;
        while (max / rate > 0) //循环最大值的位数
        {
            //清空桶
            bucket = new int[10];
            //桶中存放nums[i]的位数是桶索引的数字的个数
            for (int i = 0; i < n; i++) {
                bucket[nums[i] / rate % 10]++;
            }
            //计算桶中,当前桶加上之前的桶一共存放了多少数字,这样就可以知道这个桶中的数字,放回nums数组时,应该放在哪个位置
            for (int i = 1; i < 10; i++) {
                bucket[i] += bucket[i - 1];
            }
            //将桶中的数据,再临时放进temp数组,谁先进的谁放前面,因此,倒序出桶
            for (int i = n - 1; i >= 0; i--) {
                temp[bucket[nums[i] / rate % 10] - 1] = nums[i]; //将桶中的nums[i]放回nums数组
                bucket[nums[i] / rate % 10]--; //放回一个,该桶中的数量就减少一个
            }
            //将temp数组拷贝回nums数组
            System.arraycopy(temp, 0, nums, 0, n);
            rate *= 10;
        }
        return nums;
    }

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

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

相关文章

前端 CSS 经典:在 Vue3 中使用渐进式图片

1. 什么是渐进式图片 当我们网站会加载很多图片的时候&#xff0c;有些图片尺寸很大&#xff0c;加载就会很慢&#xff0c;会导致页面长时间陷入白屏状态&#xff0c;用户体验很不好。所以可以使用渐进式图片&#xff0c;先给用户展示模糊图&#xff0c;这些图尺寸小&#xff…

数据分析-Excel基础函数的使用

Excel基础函数&#xff1a; sum:求和 sumif:单条件求和 sumifs:多条件求和 subtotal:根据筛选求和 if:逻辑判断 vlookup:连接匹配数据 match:查找数值在区域中的位置 index:根据区域的位置返回数值 match、index:一起使用&#xff1a;自动根据列名查找数据 sumifs、match、ind…

k8s+RabbitMQ单机部署

1 k8s 配置文件yaml: apiVersion: apps/v1 kind: Deployment metadata:name: rabbitmq-deploynamespace: rz-dt spec:replicas: 1selector:matchLabels:app: rabbitmqtemplate:metadata:labels:app: rabbitmqspec:containers:- name: rabbitmqimage: "rz-dt-image-server…

ubtun虚拟机安装

选择镜像后启动 选择第一个回车 加载完成后 &#xff0c;进入Ubuntu安装界面&#xff0c;安装语言选择English&#xff0c;完成后按一下回车&#xff1a; 此时弹出安装器可更新提示&#xff0c;下方选项选择第二个Continue without updating&#xff08;不更新&#xff0c;继续…

计算机网络 —— 应用层(应用层概述及服务方式)

计算机网络 —— 应用层&#xff08;应用层概述及服务方式&#xff09; 应用层服务方式C/S&#xff08;客户端-服务器&#xff08;C/S&#xff09;模型&#xff09;基本概念特点B/S&#xff08;Browser/Server&#xff09;基本概念特点应用场景 p2p &#xff08;对等网络&#…

精彩回顾!安全智能体的前沿技术研究与实践

&#xff08;关注“安全极客”&#xff0c;回复“智能体”下载第一期系列专题PPT&#xff01;&#xff09; 近日&#xff0c;安全极客和Wisemodel社区联合发起并主办了“AISecurity”系列第1期&#xff1a;大模型与网络空间安全前沿探索线下活动。在这次活动中&#xff0c;云起…

Unity与Js通信交互

目录 1.Js给Unity传递消息 2.Unity给Js传递消息 简介: Unity 与 JavaScript 通信交互是指在 Unity 项目中实现与 JavaScript 代码进行数据交换和功能调用的过程。 在 Unity 中&#xff0c;可以通过特定的接口和技术来与外部的 JavaScript 环境进行连接。这使得 Unity 能够利…

机器学习:回顾总结

学了什么 进阶内容 接下来如何学习 找个项目自己练习多读前沿paper 学员分布

Adobe illustrator教程——超实用的三个进阶小技巧!

AI2024(64bit) Adobe illustrator 软件安装包下载地址&#xff1a; 百度网盘下载https://pan.baidu.com/s/1C10-2JVN1rxFF5VFRuV2Yw?pwdSIMS 01 进阶技巧1——曲率工具 基于之前的入门教程&#xff0c;大家肯定会快速想到“画笔工具”&#xff0c;但是画出来的曲线往往不够平…

k8s+pv+pvc+nas 数据持久化volumes使用

1 k8s pod申请持久化卷配置 apiVersion: v1 kind: Service metadata:name: $IMG_NAMEnamespace: rz-dtlabels:app: $IMG_NAME spec:type: NodePortports:- port: 8091nodePort: 31082 #service对外开放端口selector:app: $IMG_NAME --- apiVersion: apps/v1 kind: Deployment …

【Css】纯css展开、收起超出的文本

效果 展开 收起 未超出 码 -webkit-line-clamp: 3; 设置限制行数 <div class"wrap"> <inputtype"checkbox"id"exp-txt"><div class"text"><labelfor"exp-txt"class"btn"></label&g…

基于WPF技术的换热站智能监控系统09--封装水泵对象

1、添加用户控件 2、编写水泵UI 控件中用到了Viewbox控件&#xff0c;Viewbox控件是WPF中一个简单的缩放工具&#xff0c;它可以帮助你放大或缩小单个元素&#xff0c;同时保持其宽高比。通过样式和属性设置&#xff0c;你可以创建出既美观又功能丰富的用户界面。在实际开发中…

通过Stream流对集合进行操作

Stream Api是JDK8提供的新特性&#xff0c;可以更为方便地对集合进行操作&#xff0c;比如我今天遇到的一个场景&#xff1a; 将本地的一个视频文件分成多块上传到Minio服务器&#xff0c;现在上传功能已经完成&#xff0c;需要调用minioClient对已经上传的文件重新合并成一个新…

u-boot(六) - 详细启动流程

一&#xff0c;u-boot启动第一阶段 1&#xff0c;启动流程 ENTRY(_start) //arch/arm/lib/vectors.S ----b resets //arch/arm/cpu/armv7/start.S --------b save_boot_params ------------b save_boot_params_ret //将cpu的工作模式设置为SVC32模式&#xff08;即管理模式&a…

扩展方块加载动画

效果图: 完整代码: <!DOCTYPE html> <html> <head><meta charset="UTF-8" /><title>扩展方块加载动画</title><style type="text/css">body {background: #ECF0F1;display: flex;justify-content: center;al…

【并集查找】839. 相似字符串组

本文涉及知识点 并集查找&#xff08;并差集) 图论知识汇总 LeetCode839. 相似字符串组 如果交换字符串 X 中的两个不同位置的字母&#xff0c;使得它和字符串 Y 相等&#xff0c;那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的&#xff0c;那它们也是相似的。…

车载网络安全指南 系统层面开发阶段(六)

返回总目录->返回总目录<- 目录 前言 一、统层面产品开发启动 二、系统层面漏洞分析 三、网络安全策略具体化 四、确定网络安全技术需求 五、系统设计 六、系统集成与测试 七、网络安全验证 八、系统层面网络安全评估 九、系统层面产品开发阶段检查 十、产品发…

在vue中循环中调用接口-promise.all();按顺序执行异步处理

&#x1f308;&#x1f308;&#x1f308;目录 场景一 解决 场景二 解决 场景一 数组遍历中每次遍历都需要去请求getStaffCover接口&#xff0c;拿到该接口的结果拼接到数组的每一项&#xff0c;等到数组遍历完之后&#xff0c;拿到拼接好的数组。拼接的数组必须是最终遍历…

自动控制理论---零点和极点、单位脉冲响应

1、实验设备 PC计算机1台&#xff0c;MATLAB软件1套。 2、实验目的 研究四个具有相同极点分布但不同零点分布的二阶系统对单位脉冲响应的影响。绘制各系统的零点和极点分布图。计算并绘制各系统的单位脉冲响应波形。分析零点分布对单位脉冲响应的影响。 3、实验原理说明&am…

BC35 判断字母

BC35 判断字母 废话不多说&#xff0c;直接上题 解析答案&#xff1a; #include<stdio.h> int main() {int ch;while ((ch getchar()) ! EOF)if ((A < ch && Z > ch) || (a < ch && z > ch)){printf("YES");}else{printf("…