实验目的:
快速排序可以按照以下的算法思想优化,并加快快速排序的速度:即当快速排序所划分的子序列的长度小于某个定值k时,该子序列基本有序,可以采用插入排序的办法对子序列进行排序,从而使整体算法的时间复杂度的期望下降为O(nk+nlg(n/k))。本实验的目的是实现该快速排序的优化算法,并且探讨合理的k的取值范围
问题定义
实验总共要解决两个问题
1、 优化的快速排序的算法确实能够加速快速排序的速度。
2、 讨论k的合理的取值范围。
对于给定规模为n的int[]无序随机数组进行排序,通过实验证明经过优化的快速排序比传统的快排效率要高,并讨论k的值的范围。
实验思想
1、 优化快速排序的方法:
a)
在快速的排序的方法中加入判断语句,当high-low<k的时候则调用插入排序的算法,否则继续使用快速排序。
b)
当k<=2时,实质上不调用插入排序,这样就可以得出相同规模的情况下直接使用快速排序所需要的时间。从而便于比较
2、 通过考察时间消耗来确定性能的高低
a)
每次计算数据都取一定规模的int 32型无序随机数进行排序,为了避免误差,规模n一定时,不同的k值,都计算5次运算时间,取平均值记录。
b)
使用.net framework 2.0提供的Stopwatch计时器对象,该对象可以将时间间隔精确到0.0001ms。
c)
从理论上得到合理的k值的取值范围是k<=logn.因此在验证取值范围的时候要取到log n 两侧的值。
d)
通过比较时间复杂度来计算性能提升的多少,从而得到加快了快速排序的结论,以及合理的k的取值范围。
测试数据及结果
本测试的硬件以及软件环境如下
CPU:PM 1.5G; 内存:768M;操作系统:windows xp sp2;软件平台:.net 2.0;
1、 数组规模为50的时候得到如下数据。
其中第一行为k的取值、第二行为程序运行所需要的时间,单位为ms。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/icyfire0105/image001.gif)
2、 数组规模为500的时候得到如下数据。
其中第一行为k的取值、第二行为程序运行所需要的时间,单位为ms。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/icyfire0105/image002.gif)
整体图
![](https://p-blog.csdn.net/images/p_blog_csdn_net/icyfire0105/image003.gif)
局部图
3、 数组规模为5000的时候得到如下数据。
其中第一行为k的取值、第二行为程序运行所需要的时间,单位为ms
![](https://p-blog.csdn.net/images/p_blog_csdn_net/icyfire0105/image004.gif)
4、 数组规模为50000的时候得到如下数据。
其中第一行为k的取值、第二行为程序运行所需要的时间,单位为ms
![](https://p-blog.csdn.net/images/p_blog_csdn_net/icyfire0105/image005.gif)
5、 数组规模为1,000,000的时候得到如下数据。
其中第一行为k的取值、第二行为程序运行所需要的时间,单位为ms
![](https://p-blog.csdn.net/images/p_blog_csdn_net/icyfire0105/image006.gif)
结果分析:
1、 由所有的图可以看出,经过优化以后的快速排序比传统快速排序的速度要快,通过数据计算可以排序速度提高了10%-20%左右。
2、 通过图示也可以知道当k=logn的时候,其效率提升并不是最大的,在规模不大(例如5个数量级以下)的排序中其最佳的k的取值往往比log n大,一般以8—12之间为最小。
当规模较大时,一般取logn为宜,即使最佳取值超过logn其性能提升也不明显。
3、 此后随着k的取值的增大,尤其是超过50之后,时间复杂度明显提升,甚至比快速排序的算法要差。
4、 在规模较大的排序过程中快速排序的效率明显好于插入排序。
有可能影响结论的因素:
1、 快速取随机数的算法:
a)
在本实验中,所使用的随机数是在10n的整数内取n个无重复的随机数,该算法有可能会影响对实验结果的分析有轻微影响。
2、 小规模的数组的分析
a)
对于小规模的数组有可能在快速排序之后得到的子序列的长度小于8,因此直接取8值得商榷。
实验结论
1、 经过优化以后的快速排序比传统快速排序的速度要快,通过数据计算可以排序速度提高了10%-20%左右。
2、 在规模不大(例如5个数量级以下)的排序中其最佳的k的取值往往比log n大,一般以8—12之间效率最佳。
当规模较大时,k的取值一般取logn为宜,即使最佳取值超过logn其性能提升也不明显。
源代码
优化排序的算法源代码(C#描述)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)