对一亿个数据排序时间少于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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/qq_33700123/article/details/103444179
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/838862

相关文章

使用Vue-ECharts实现数据可视化图表功能

《使用Vue-ECharts实现数据可视化图表功能》在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所... 目录前言为什么选择 vue-ECharts?1. 基于 ECharts,功能强大2. 更符合 Vue

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>

Python实现获取带合并单元格的表格数据

《Python实现获取带合并单元格的表格数据》由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,所以本文我们就来聊聊如何使用Python实现获取带合并单元格的表格数据吧... 由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,现将将封装成类,并通过调用list_exc

Mysql数据库中数据的操作CRUD详解

《Mysql数据库中数据的操作CRUD详解》:本文主要介绍Mysql数据库中数据的操作(CRUD),详细描述对Mysql数据库中数据的操作(CRUD),包括插入、修改、删除数据,还有查询数据,包括... 目录一、插入数据(insert)1.插入数据的语法2.注意事项二、修改数据(update)1.语法2.有

Python日期和时间完全指南与实战

《Python日期和时间完全指南与实战》在软件开发领域,‌日期时间处理‌是贯穿系统设计全生命周期的重要基础能力,本文将深入解析Python日期时间的‌七大核心模块‌,通过‌企业级代码案例‌揭示最佳实践... 目录一、背景与核心价值二、核心模块详解与实战2.1 datetime模块四剑客2.2 时区处理黄金法

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增

Pandas进行周期与时间戳转换的方法

《Pandas进行周期与时间戳转换的方法》本教程将深入讲解如何在pandas中使用to_period()和to_timestamp()方法,完成时间戳与周期之间的转换,并结合实际应用场景展示这些方法的... 目录to_period() 时间戳转周期基本操作应用示例to_timestamp() 周期转时间戳基