- 实验目的:
- 掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理
- 掌握不同排序算法时间效率的经验分析方法,验证理论分析与经验分析的一致性。
- 问题重述(问题描述):
问题一:
实现选择排序、冒泡排序、合并排序、快速排序、插入排序算法
问题二:
生成20组数量规模为n(10万,20万,30万,40万,50万)的待排序随机数,然后用上述五种排序算法计算这20个样本的平均运行时间。并且要做出这五个排序算法在20个随机样本的平均运行时间,理论运行时间与输入规模n的关系曲线图(横纵坐标都要均匀)。比较两条曲线,理论和实际是否一致,不一致要分析给出原因。
问题三:
有10亿的数据(每个数据四个字节),请快速挑选出最大的十个数,并在小规模数据上验证算法的正确性。
- 实验原理(代码思想以及求解问题的算法原理描述):
- 选择排序:
第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素。(一般都是挑最小的数)
Fig1:选择排序原理图
2.冒泡排序:
相邻的两个元素进行比较,按照要求进行交换。
Fig2:冒泡排序原理图
3.合并排序:
先将数组中的元素拆分成若干小部分,然后再将这些小部分按照顺序进行重新组合,从而实现排序。(有点分治法的味道)
4.快速排序:
将比这个数大或等于的数全放到它的右边,小于它的数全放到它的左边(为由小到大排序)
5.插入排序:
将一个数插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。
6.TOP 10:
按照正常思路肯定是便利数据10遍选择最大的十个数(即为选择排序)
可以选取上述五种排序算法中的最高效的来排序。
堆排序,维护10个数的小顶堆。
理论分析:
每个数据是4字节,那么10亿个数据就是40亿byte=3.725 G;所以在测试TOP 10时要预留足够的储存空间来存放待排的样本。
三、实验内容:
排序问题要求我们按照升序排列给定列表中的数据项,目前为止,已有多种排序算法提出。本实验要求掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理,并进行代码实现。通过对大量样本的测试结果,统计不同排序算法的时间效率与输入规模的关系,通过经验分析方法,展示不同排序算法的时间复杂度,并与理论分析的基本运算次数做比较,验证理论分析结论的正确性。
流程图
- 实验过程及其优化分析(算法实现的核心伪代码以及算法测试结果及效率分析):
设计随机数生成20组样本:
先是设置生成随机数样本,一开始使用的是rand()这个函数;但发现每次产生的随机数虽然随机,但每个生成的随机数样本是一模一样的,缺乏说服力。然后我就是又去查了一下其他的生成随机数的方法mt19937随机数方法。
Fig:生成随机数的伪代码
通过小规模的数据生成发现:mt19937 随机数引擎生成的数比较随机,且数的范围比较大,数据比较杂乱,会使得我们后续的排序实验更加具有说服力。
接着为了更加方便我们跑数据我直接让程序一次性跑完20个样本并且把算出的数据给跳出来,解放劳动力。
Fig:一起运行20个样本的伪代码
- 选择排序(O(n2)):
1.1简单选择排序:
第一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素。
Fig3:选择排序伪代码
实际:
数据规模n |
100000 |
200000 |
300000 |
400000 |
500000 |
运行时间/ms |
5657 |
23451 |
54387 |
98447 |
154215 |
理论:
数据规模n |
100000 |
200000 |
300000 |
400000 |
500000 |
运行时间/ms |
5657 |
22784 |
51264 |
91136 |
142400 |
</