湖南新备案的网站高明网站建设
web/
2025/10/2 0:45:55/
文章来源:
湖南新备案的网站,高明网站建设,做网站用图片算侵犯著作权吗,wordpress 5.5客户端目录
一、实验目的
二、实验概述
三、实验内容
四、问题描述
1.实验基本要求
2.实验亮点
3.实验说明
五、算法原理和实现
问题1-4算法
1. 选择排序
算法实验原理
核心伪代码
算法性能分析
数据测试
选择排序算法优化
2. 冒泡排序
算法实验原理
核心伪代码 算…目录
一、实验目的
二、实验概述
三、实验内容
四、问题描述
1.实验基本要求
2.实验亮点
3.实验说明
五、算法原理和实现
问题1-4算法
1. 选择排序
算法实验原理
核心伪代码
算法性能分析
数据测试
选择排序算法优化
2. 冒泡排序
算法实验原理
核心伪代码 算法性能分析
数据测试
3. 快速排序
算法实验原理
核心伪代码
算法性能分析
数据测试
4. 合并排序
算法实验原理
核心伪代码
算法性能分析
数据测试
优化模型
5. 插入排序
算法实验原理
算法性能分析
数据测试
问题5算法
方法一: 排序查找
方法二: 选择查找
方法三: 优先队列
六、实验结果和分析
七、实验结论 一、实验目的
1、掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理
2、掌握不同排序算法时间效率的经验分析方法验证理论分析与经验分析的一致性。 二、实验概述
排序问题要求我们按照升序排列给定列表中的数据项目前为止已有多种排序算法提出。本实验要求掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理并进行代码实现。通过对大量样本的测试结果统计不同排序算法的时间效率与输入规模的关系通过经验分析方法展示不同排序算法的时间复杂度并与理论分析的基本运算次数做比较验证理论分析结论的正确性。 三、实验内容
1、实现选择排序、冒泡排序、合并排序、快速排序、插入排序算法
2、以待排序数组的大小n为输入规模固定n随机产生20组测试样本统计不同排序算法在20个样本上的平均运行时间
3、分别以n10000, n20000, n30000, n40000, n50000等等重复2的实验画出不同排序算法在20个随机样本的平均运行时间与输入规模n的关系如下图1所示 图1. 时间效率与输入规模n的关系图
4、画出理论效率分析的曲线和实测的效率曲线注意由于实测效率是运行时间而理论效率是基本操作的执行次数两者需要进行对应关系调整。调整思路以输入规模为10000的数据运行时间为基准点计算输入规模为其他值的理论运行时间画出不同规模数据的理论运行时间曲线并与实测的效率曲线进行比较。经验分析与理论分析是否一致如果不一致请解释存在的原因。
5、现在有10亿的数据每个数据四个字节请快速挑选出最大的十个数并在小规模数据上验证算法的正确性。 四、问题描述
1.实验基本要求 ①实现选择排序、冒泡排序、合并排序、快速排序、插入排序五大排序算法的算法实现原理 ②计算各个排序在不同规模下算法的运行时间并画出理论分析效率分析的曲线和实测的效率曲线比较经验分析和理论分析是否一致并给出原因 ③根据排序在不同规模下算法的运行时间画出不同排序算法在20个随机样本的平均运行时间与输入规模n的关系并比较各个排序算法之间的优缺点 ④设计算法使之能从10亿数据中快速挑选出最大的十个数并通过小规模数据验证算法的正确性
2.实验亮点
①实现了对部分算法的优化在面对大规模数据排序时合并排序以及快速排序可以发挥很大的作用
②成功实现从10亿数据中快速挑选最大的十个数
③对实验过程中发现的相关问题进行了探究并解决
3.实验说明 ①实验结果均以秒为单位使用双精度浮点数存储 ②相关运行时间仅包括排序程序运行时间不包括其它时间 ③以输入规模为10000的数据运行时间为基准点计算输入规模为其他值的理论运行时间 ④所有运行时间都是在测试样本为20的基础下进行平均测量的 五、算法原理和实现
求解问题的算法原理描述包括算法实现的核心伪代码不可贴源码及解释。
问题1-4算法
1. 选择排序
算法实验原理 每次从待排序的序列中找出最小值存放在序列起始位置继续从剩余未排序元素中寻找最小值放到已排序列末尾直达全部待排数据排完即可
核心伪代码 算法性能分析 选择排序的外层循环需要进行n次内部的交换操作介于0与n-1次之间比较操作介于0与n(n-1)/2次之间赋值操作介于0与3(n-1)次之间比较次数为O(n^2) 在最好的情况下数据已经有序共交换0次最坏情况下交换n-1次进行n(n-1)次比较故选择排序的时间复杂度为O(n^2)
数据测试 数量级 10000 20000 30000 40000 50000 实际 0.13825 0.5527 1.2447 2.2526 3.59165 理论 0.13825 0.553 1.24425 2.12 3.45625
根本上述实际运行时间和理论运行时间可以做出下图: 从该图中我们可以看出图像基本符合二次增长 从上表和上图中可以发现整体时间消耗都大致满足数量规模扩大到原来的n倍时时间消耗扩大n^2的规律
选择排序算法优化
算法每次把数据全部搜索一边但只排好一个数据有点太浪费时间了因此可以将其优化为每次循环找出该序列中的最大最小值这样每次排好两个数据可以将循环的次数减少一半但其算法时间复杂度仍为O(n^2) 改善前与改善后选择排序对于10000-50000数据运行时间如下表所示 数据级 10000 20000 30000 40000 50000 优化前 0.365 1.583 3.816 7.431 11.992 优化后 0.332 1.467 3.645 6.9 11.051
可得图表 2. 冒泡排序
算法实验原理 从左边开始依次比较相邻的元素若左边大于右边则交换它们的位置继续第一步操作知道来到数据的右边此时右边第一个位置 为最大的元素重复进行直到没有元素需要比较排序完成
核心伪代码 算法性能分析 由伪代码可知最好情况下排序前已经有序只执行一趟总比较次数为n-1,移动次数为0最坏情况下排序前是逆序则每趟排序都需要比较i-1次并移动i-1次 总比较次数为n^2/2,总移动次数为n^2/2 在最好的情况下只需要进行外部循环时间复杂度为O(n)在最坏的情况下时间复杂度为O(n^2)
数据测试 数量级 10000 20000 30000 40000 50000 实际 0.36115 1.56725 3.84645 7.3222 12.1892 理论 0.36115 1.4446 3.25035 5.7784 9.02875 根本上述实际运行时间和理论运行时间可以做出下图: 由于冒泡排序算法时间复杂度为O(n^2)故数量级扩大10倍时时间消耗应扩大100倍。由上图可得随着数据量的增大拟合效果越好所有实验数据符合O(n^2)的时间复杂度。且 可以看出当数量级逐渐增大时实际时间消耗与理论实践消耗有比较大的区别且随着数量级的增大彼此之间的区别也越来越大拟合效果变差。经过分析选择排序进行了很多次相互调换元素的操作从而造成元素浪费因此我进行了两次对比试验使用库函数 swap函数和手写调换元素的函数进行对比可以发现在大规模数据的背景下手写函数的拟合效果更好性能更优异。 3. 快速排序
算法实验原理 选择一个枢轴元素: 从待排序序列中选择一个元素作为枢轴元素一般可选择第一个元素或者最后一个元素借此将该序列分为两个部分将待排序序列中小于枢轴元素的值放到左边大于枢轴元素的放在右边再次对左右两部分分别进行快速排序递归地划分后得到的左右两部分分别进行排序直到整个序列有序
核心伪代码 算法性能分析 快速排序的一次划分算法需要两头交替搜索直到i、j重合找到一个pivot值因此该步骤其时间复杂度为O(n)而整个快速排序算法的时间复杂度还与其划分的次数有关。在最好的情况下每次划分几乎都将当前序列等分处理即仅需经历logn次划分便可实现子表长度为1这样整体的时间复杂度为Ologn*n在最坏的情况下每次选的pivot值均为当前序列的最大或最小元素则需要经历n次划分才能实现目标则此时整体的时间复杂度为On^2
综上分析快速排序的平均时间复杂度为On*logn
数据测试 数量级 10000 20000 30000 40000 50000 实际 0.0014 0.00315 0.0045 0.00685 0.0083 理论 0.0014 0.00301 0.0047 0.00644 0.0082 根本上述实际运行时间和理论运行时间可以做出下图: 结合上表和上图我们可以看出整体时间消耗都大致满足O(nlogn)的时间复杂度。且数据拟合效果很好 最差情况下快速排序的表现—当待排数据以逆序顺序待排时快速排序所用时间与归并排序时间消耗对比由于栈空间溢出等问题最大数据我只能测量到30000 数量级 5000 10000 15000 20000 30000 快速排序 0.024 0.088 0.195 0.346 0.78 递归归并排序 0.001 0.003 0.004 0.006 0.009 可以看到快速排序时间复杂度退化到O(n^2)运行效率远不如合并排序每次操作只能够确定一个元素的位置同时进行了n-1次移动且由于要递归调用n-1次递归树的深度达到了O(n)
4. 合并排序
算法实验原理 将待排序的线性表不断地切分成若干子表直到每个子表都只包含一个元素此时可认为只包含一个元素的子表为有序表将子表一一合并每合并一次就会产生一个新的且更长的有序表重复操作直至只剩下一个子表即为有序表
核心伪代码 算法性能分析 根据分治法递归可以求出其递归式:
T(n) 2* T(n/2) t 利用主方法不能求解出其时间复杂度为O(nlogn) 如果待排序的记录为n个则需要做log2n趟两路归并排序每趟两路合并排序的时间复杂度为O(n)合并排序的时间复杂度为O(nlog2n)归并排序的空间复杂度是O(n)
数据测试 数量级 10000 20000 30000 40000 50000 实际 0.0038 0.0072 0.01155 0.01565 0.0208 理论 0.0038 0.0081 0.01275 0.01748 0.0223 根本上述实际运行时间和理论运行时间可以做出下图: 从图像上来看时间消耗曲线基本是线性的但其实是因为n的规模还不够大体现不出对数函数的曲线特性从数据上来看规模扩大n2/n1倍时间扩大为原来的n2/n1*log(2, n2)/log(2, n1)倍几乎符合拟合效果比较好符合时间复杂度为O(nlogn)实际时间消耗曲线一直在理论时间消耗曲线附近波动其原因为时间级较少误差较大。
优化模型
非递归实现的合并排序 在上述合并排序的实现中我采用的是递归实现的合并排序从存储上看递归实现的归并其实是对递归树的自顶向下的先序遍历而非递归归并 是对递归树自顶向下的层次遍历相对于递归可以节省大量时间和空间
非递归实现合并排序伪代码 为了验证非递归合并排序算法的优异性我对比了递归实现以及非递归实现合并排序在面对大规模数据排序时的性能当测试规模在1000000-10000000变化时消耗时间如下表所示 数量级 1000000 2000000 4000000 8000000 10000000 递归实现 0.475 0.966 1.941 4.087 5.297 非递归实现 0.422 0.817 1.722 3.656 4.582 从上图可见使用非递归实现的时间消耗小于使用递归实现的合并排序在大规模数据处理中性能会更加优异
5. 插入排序
算法实验原理 从左边第二个元素开始向左侧一一比较大小若比位置元素小则向左移动直到该位置上的元素比该元素小则将元素放在该位置的后一个位置重复循环直到右侧元素全部排序完成
核心伪代码 算法性能分析 在最好的情况下此时整个序列已经有序只需要进行外部循环总比较次数为n-1,移动次数为0此时时间复杂度为O(n); 在最坏的情况下排序前整个序列为逆序每趟排序都要比较i-1次并移动i-1次总比较和移动的次数均为n^2/2
数据测试 数量级 10000 20000 30000 40000 50000 实际 0.10215 0.414 0.9426 1.7219 2.7398 理论 0.10215 0.4086 0.91935 1.6344 2.55375 根本上述实际运行时间和理论运行时间可以做出下图: 由于插入排序算法时间复杂度为O(n^2)故数量级扩大10倍时时间消耗应扩大100倍。由上图可得随着数据量的增大拟合效果越好所有实验数据符合O(n^2)的时间复杂度。且图像实际时间消耗曲线与理论时间消耗也基本吻合。 问题5算法
方法一: 排序查找
算法实验原理
将全部数据降序排序后输出前k个数据即可
核心伪代码 算法性能分析
选择归并排序/快速排序时间复杂度为O(nlogn) 方法二: 选择查找
算法实验原理
重复k次循环每次寻找到最大值后记录并将其设置为最小值
核心伪代码 算法性能分析
由伪代码可知算法共需要进行k次循环其时间复杂度为O(k),其中每次查找最大数都需要遍历整个数据时间复杂度为O(n)因此总体时间复杂度为O(kn) 方法三: 优先队列
算法实验原理 priority_queue 优先队列是一个具有权值的queue其内部元素按照元素的权值排列权值较高者排在最前优先出队其中缺省情况下系统会通过一个max-heap以堆实现排序特性表现为vector表现的完全二叉树 限制优先队列的大小为k当size未达到k时直接存入当达到k时比较其中最小的元素存储在top上若大则先弹出原先数字并压入该数进优先队列随后优先队列重新进行内部排序存储在首位的依旧是十个数中的最小值便于比较
核心伪代码 算法性能分析
该算法只需要遍历一次数据其算法时间复杂度为O(nlogk) 六、实验结果和分析
算法测试结果和效率分析。
问题1-4
五大排序运行时间数据总览 数量级 10000 20000 30000 40000 50000 选择排序 0.13825 0.5527 1.2447 2.2526 3.59165 冒泡排序 0.36115 1.56725 3.84645 7.3222 12.1892 合并排序 0.0038 0.0072 0.01155 0.01565 0.0208 快速排序 0.0014 0.00315 0.0045 0.00685 0.0083 插入排序 0.10215 0.414 0.9426 1.7219 2.7398
将数据可视化做成图表如下所示: 我们可以清晰的看出: 当数量级很小时六种排序方式都比较省时间当数量级在10^4左右时其算法的时间消耗差距不大但当数据量较大时快速排序、合并排序有着十分明显的优势插入排序和选择排序性能中规中矩而冒泡排序则需要小号更多的时间去完成排序操作 对于数据量较少时时间复杂度O(n^2)的算法和时间复杂度为O(nlogn)的算法区别不大都能较好的完成排序当数据量变大时时间复杂度为O(nlogn)的算法便会体现出明显的优势因此当数据量较大时我们应该优先采取快速排序合并排序等算法 问题5
小规模数据测试
令输入的向量值为572185423436985634123246577831351030共20个数运行程序可得到三种方法运行的结果如下: 即满足查找最大的十个数进一步验证了算法的正确性
大规模数据计算 将输入规模从1000000 至 10000000变化同样进行20次测试并取平均值令k10可得到以下运行时间:
数据总览 数量级 1000000 2000000 4000000 8000000 10000000 方法一 0.2673 0.5566 1.1375 2.3171 2.92715 方法二 0.1763 0.33785 0.67795 1.3776 1.7324 方法三 0.0107 0.2125 0.04205 0.08275 0.10405 将数据可视化做成图表如下所示: 我们可以清晰的看出:
方法一排序方法的时间复杂度最高为O(nlogn)查找的速度最慢方法二比方法三的速度慢其原因为方法三只需要进行一次遍历而方法二需要进行k次遍历方法二和方法三均为线性复杂度但由于此题k值不变均无法体现 继续对第三种方法进行规模测试输入规模从100000000到1500000000 变化从运行时间可以看出依旧可以迅速得到最大的十个数: 数量级 100000000 500000000 800000000 100000000 1500000000 方法三 1.126 5.844 9.088 11.481 17.016
可见算法三对应用于大规模数据的正确性 七、实验结论
从算法解决问题的角度写你得到的结论是什么注意不要写个人心得。
当调用相关函数时若参数传递为引用传递或指针传递时传输效率会明显高于直接传值能够有效提高程序运行的效率减少无效循环次数不能提升算法的效率 在冒泡排序中我试图设置标志若不在进行交换操作则意味着序列已经有序因此我设置了如下代码进行测试 运行结果如表 数量级 10000 20000 30000 40000 50000 无优化 0.379 1.625 3.986 7.47 12.199 优化 0.383 1.667 4.158 7.716 12.244 可见不但没有优化性能还增加了运行时间 在面对大规模数据需要处理时我们要选择时间复杂度低的算法进行实验并且在编写代码时也要尽力降低算法的时间复杂度
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/85336.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!