对一亿个数据排序时间少于1秒排序算法WaveSort

2024-03-23 16:10

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

    前言:干货干货,作者偶然在工作中悟出来了一种排序算法,听标题就很牛逼,下面开始一一让大家了解此算法。

一、首先我们直接与现有的排序算法:快速排序、C++库里的Sort、计数法桶排序进行速度对比

1、如图所示,这就是测试所需要的数据和方法。

2、用1000个升序数据进行排序,小于几毫秒我就不写了,直接写毫秒

C++Sort时间为:2ms,快排:2ms,波浪:1ms,桶排1ms,桶排永远都很快,它是消耗空间获取速度的,如果不懂桶排可以先去学习下。

3、1000个升序数据,然后随机打乱1000次,注意打乱是指随机1000个位置,然后每个位置的数也随机,所以最后出来的数据大多数可能都是有点顺序的。

C++Sort时间为:2ms,快排:1ms,波浪:1ms,桶排1ms

3、用10000个升序数据进行排序

C++Sort时间为:7ms,快排:127ms,波浪:1ms,桶排1ms

4、10000个升序数据,然后随机打乱10000次

C++Sort时间为:16ms,快排:2ms,波浪:45ms,桶排1ms

4、一百万个升序数据

C++Sort时间为:968ms,快排:作者等不下去了,波浪:3ms,桶排15ms,有序作者的O(n)的,快排O(N^2),到这里其实作者的排序算法作用还没很好体现,下面开始就露出水面了。

5、一百万个升序数据,随机打乱10000次

C++Sort时间为:973ms,快排:等不下去,波浪:220ms,桶排14ms

5、一百万个升序数据,随机打乱一百万次

C++Sort时间为:994ms,快排:等不下去,波浪:656ms,桶排15ms

6、一千万个升序数据

C++Sort时间为:等不下去,快排:等不下去,波浪:23ms,桶排140ms

6、一千万个升序数据,随机打乱一千万次

C++Sort时间为:12s,快排:等不下去,波浪:666ms,桶排139ms

7、一亿万个升序数据

C++Sort时间为:等不下去,快排:等不下去,波浪:226ms,桶排1391ms

7、一亿万个升序数据,随机打乱1次

C++Sort时间为:等不下去,快排:等不下去,波浪:224ms,桶排1370ms

 

8、一亿万个升序数据,随机打乱一万次

C++Sort时间为:等不下去,快排:等不下去,波浪:430ms,桶排1378ms

9、一亿万个升序数据,随机打乱一百万次

C++Sort时间为:等不下去,快排:等不下去,波浪:868ms,桶排1409ms

10、一亿万个升序数据,随机打乱亿万次

C++Sort时间为:等不下去,快排:等不下去,波浪:868ms,桶排1397ms

11、一亿万个升序数据,随机打乱一亿万次,波浪的空间复杂度是O(1),不管多少次,波浪空间复杂度都是O(1),递归次数2,其实递归是1,因为加了优化多了个函数还没介绍,后面介绍。

从以上测试表明作者的波浪是不是屌爆了,是的,其实波浪算法也是有优缺点的,如果读者有认真读或许已经猜到了。

优点:如果数据越有序速度越快,平均时间复杂度O (nlogn),最快O(n),最慢O(n^2)

缺点:很乱的一组数据非常不友好,它跟快排是相反的,快排越乱越快,但是好处是快排超过百万数据就算很乱也要排很久

波浪就算1亿个数据,只要不要乱到完全无序还有点秩序都非常快。

二、波浪算法优化    

       假设在一亿个数据中被改变了几百万或几千万数据,这时的数据虽然还有点点秩序但其实很乱了,这个时候如果用快速排序先排N遍到有点秩序了再用波浪排就会提高速度,下面作者表演针对这类数据的优化操作。

      1、一亿万个升序数据,随机打乱一亿次,进行在波浪排序前先快速排序递归10000遍,第三个参数就是快排递归几遍。

           优化前:886ms,优化后:539ms,

   

2、一亿万个升序数据,随机打乱一百万次

           优化前:913ms,优化后:565ms,

3、一亿万个升序数据,随机打乱十万次

           优化前:869ms,优化后:764ms,

4、一亿万个升序数据,随机打乱一万次

           优化前:445ms,优化后:1456ms,

5、十万个升序数据,随机打乱十万次

           优化前:445ms,优化后:106ms,

测试所得:此类优化作者已经测试只适用于数据超过10万,数据低于10万时快排递归次数设置为0合适,并且数据被打乱小于100000都不要使用哪怕一次递归快排。

总结:波浪非常适用有秩序的数据组中改变一些值导致无序的数据组进行排序,如果你有一股已排序数据,当其中一个或多个数据发生改变导致秩序变化时,这时候波浪就是最好选择。、

三、实现原理

        下面是以升序排序为例,index会一直往右边移动,当发现当前元素大于下一个元素时,这时将下一个元素往回滚动并与每一个元素比较,比它大的都往后面挪动一次,直到找到等于或小于它的元素时就将它放到该元素后面,然后index继续右移判断,就这样以此类推。

     数据3、4、2、5、7、10、4,波浪排序比较13次,快速排序比较23

源码:

int counts = 0;
int Prob = 0;
class WaveSort
{
public:template<class T>static void SortFaser(T *arr, int left, int right){if (left < right){if (counts++ >= Prob)return;int tmp = Tmp(&*arr, left, right);SortFaser(&*arr, left, tmp - 1);SortFaser(&*arr, tmp + 1, right);}}template<class T>static int Tmp(T * arr, int left, int right){T tmp = arr[left];while (left < right){while (left < right && tmp <= arr[right]){right--;}arr[left] = arr[right];while (left < right && tmp >= arr[left]){left++;}arr[right--] = arr[left];}arr[left] = tmp;return left;}template<class T>static void Sort(T * arr,const int nLen,int FaserCount){Prob = FaserCount;//快排递归次数SortFaser(arr, 0, nLen - 1);if(nLen <= 1) {return;}T oCompareItem;int nEnd = -1;int eIndex = -1;int bIndex = -1;bool isOne = true;while(true){/*for(int i = 0; i < 16; i++){cout<<arr[i]<<" ";}cout<<endl;*///找到第一个小于自己前一个元素的元素for(eIndex = eIndex + 1; eIndex < nLen - 1; eIndex++){if(arr[eIndex] > arr[eIndex + 1]){oCompareItem = arr[eIndex + 1];nEnd = eIndex;break;}	}//不需要排序或已经到结尾了if(nEnd == -1 || eIndex == nLen - 1){return;}arr[nEnd + 1] = arr[nEnd--];isOne = true;//把前面大于自己的元素往后移动一位for(bIndex = nEnd; bIndex >= 0; bIndex--){if(arr[bIndex] > oCompareItem){arr[bIndex + 1] = arr[bIndex];}else{arr[bIndex + 1] = oCompareItem;isOne = false;break;}	}if(isOne){arr[0] = oCompareItem;}}	}
};

完整工程文件

这篇关于对一亿个数据排序时间少于1秒排序算法WaveSort的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

使用SpringBoot+InfluxDB实现高效数据存储与查询

《使用SpringBoot+InfluxDB实现高效数据存储与查询》InfluxDB是一个开源的时间序列数据库,特别适合处理带有时间戳的监控数据、指标数据等,下面详细介绍如何在SpringBoot项目... 目录1、项目介绍2、 InfluxDB 介绍3、Spring Boot 配置 InfluxDB4、I

MySQL按时间维度对亿级数据表进行平滑分表

《MySQL按时间维度对亿级数据表进行平滑分表》本文将以一个真实的4亿数据表分表案例为基础,详细介绍如何在不影响线上业务的情况下,完成按时间维度分表的完整过程,感兴趣的小伙伴可以了解一下... 目录引言一、为什么我们需要分表1.1 单表数据量过大的问题1.2 分表方案选型二、分表前的准备工作2.1 数据评估

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

Python实现数据可视化图表生成(适合新手入门)

《Python实现数据可视化图表生成(适合新手入门)》在数据科学和数据分析的新时代,高效、直观的数据可视化工具显得尤为重要,下面:本文主要介绍Python实现数据可视化图表生成的相关资料,文中通过... 目录前言为什么需要数据可视化准备工作基本图表绘制折线图柱状图散点图使用Seaborn创建高级图表箱线图热