Java算法之 排一亿个随机数

2023-12-24 00:30

本文主要是介绍Java算法之 排一亿个随机数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

插入排序狭义上指的是简单插入排序(选择集合,比较大小,插入元素),广义上还应该包括希尔排序(分治思想)及其两种实现方式,

最激动人心的是 , 希尔排序(移位法)的效率奇高, 在本地调试中,一亿 个随机数仅需30S即可排完 (不同机器可能结果不同) ,在数据量较大时效率是比堆排序要高的

结果在希尔排序移位法的第3点中 , 可以直接跳转查看

下面将介绍这几种排序方式及其同异点


提示:以下是本篇文章正文内容,下面案例可供参考

一、直接插入排序

1. 图解插排

思路 : 字面意义,插入是将某一元素按某种规则放入到特定集合中 ,因此我们需要将序列划分成为两块 ,一部分为有序集合, 另一部分为待排序集合

图解 :
在这里插入图片描述

为了方便理解,我们就按最最最特殊的4321序列来举例,

根据上述的思路 ,我们需要将序列划分为两部分, 为了编码方便,我们将第一个元素假设为有序集合, 那么我们的循环应当是从第2个元素开始的,也就是3

为避免后面操作把3覆盖掉了 , 我们选择一个临时变量来保存3.也就是上文的 val=arr[1] ,

由于是对数组继进行操作 , 我们同时也需要获取有序集合的最后一个元素的索引作为游标

当游标不越界 , 且待插入的值小于游标指示位置时(上图的4<3) , 我们将元素4后移 , 游标前移,继续检查集合中的其它元素是否也小于待插入的元素, 直到游标越界

上图由于集合内只有一个4, 游标前移越界了, 因此循环终止. 下一轮比较开始执行

2. 代码实现

public static void insertSort(int[]arr){for(int i = 1 ; i < arr.length; i++){int val = arr[i];int valIndex = i - 1; //游标while(valIndex >= 0 && val < arr[valIndex]){ //插入的值比游标指示的值小arr[valIndex + 1] = arr[valIndex];valIndex--; //游标前移}arr[valIndex+1] = val;}}
1234567891011

3.性能检测与时空复杂度

实际运行80w个数据耗时1分4秒(非准确值,每台机器可能都不一样)
在这里插入图片描述

直接插排在排序记录较少, 关键字基本有序的情况下效率较高

时间复杂度 :
关键字比较次数 : KCN=(n^2)/2 总移动次数 : RMN= (n^2)/2

因此时间复杂度约为 O(N^2)

二、希尔排序(交换法)

1. 思路图解

在这里插入图片描述

2. 代码实现

public static void shellSort(int[] arr){ //交换法int tmp = 0;for(int gap = arr.length / 2 ; gap > 0 ; gap /= 2){for(int i = gap ; i < arr.length ; i++){ //先遍历所有数组for(int j  = i - gap ; j >= 0 ; j -= gap){//开启插入排序if(arr[ j ] > arr[ gap + j ]){ //可以根据升降序修改大于或小于tmp = arr[gap + j];arr[j+gap] = arr[j];arr[j] = tmp;}}}System.out.println(gap);System.out.println(Arrays.toString(arr));}}
12345678910111213141516

这里最难理解的应该是第三个for循环,j = i - gap, 表示小组内的第一个元素,即j=0,

当小组内的第一个元素大于第二个元素时(由于是逻辑上的分类,第二个元素的索引应当是第一个元素的所有值+增量gap) , 交换两者,反之j-=gap,继续比较或跳出循环 ,

如此往复将所有小组都遍历完之后 , 缩小增量(即gap/=2) , 然后继续上述步骤, 直到增量gap为1时, 序列排序结束

3. 时间复杂度

希尔排序的时间复杂度取决于增量序列的函数 , 需要具体问题具体分析,并不是一个确定的值,这也是第四点需要讨论的问题

4. 关于增量的选择

上述我们在做排序的时候增量缩减选用的时gap/=2的模型, 这并不是最优的选择 , 关于增量的选取 , 属于数学界尚未解决的一个问题

但是可以确定的是, 通过大量的实验证明 ,当n->无穷大时, 时间复杂度可以减少到 :
在这里插入图片描述

在下一点, 移位法中 , 我们也做了几个实验 , 可以肯定的时,对于一定规模内(如800w~1亿) 的计算, 希尔排序的速度远远超过了堆排序, 至少在笔者的电脑上是这样的

三、希尔排序(移位法)

交换法的速度比移位法慢很多 ,因此更多的是使用地移位法,并且移位法相较于交换法, 更"像"插入排序

1. 思路

思路其实就是上述两种排序的结合 , 将分组插入的优点结合到一起, 效率非常高

体现的就是分治的思路,将一个较大序列切割成若干较小序列

在这里插入图片描述

2. 代码实现

public static void shellSort02(int[] arr){ //移位法for(int gap = arr.length/2 ; gap > 0 ; gap /= 2){ //分组for(int i = gap ; i < arr.length ; i++){ //遍历int valIndex = i;int val = arr[valIndex];if(val < arr[valIndex-gap]){ //插入的值小于组内另一个值while(valIndex - gap >=0 && val < arr[valIndex-gap]){ //开始插排// 插入arr[valIndex] = arr[valIndex-gap];valIndex -= gap; //让valIndex = valIndex-gap (游标前移)}}arr[valIndex] = val;}}}
12345678910111213141516

3. 实验结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这篇关于Java算法之 排一亿个随机数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/529990

相关文章

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2