【算法设计与分析】1.排序算法性能分析

相关资源下载链接

要求pdf+报告word+pre ppt+cpp源代码大礼包

cpp源代码

pre ppt

报告word

目录

写在前面的话

概览

算法原理

排序算法及伪代码

选择排序

选择排序伪代码:

冒泡排序

冒泡排序伪代码:

合并排序

效率高吗?

快速排序伪代码

快速排序伪代码

插入排序

插入排序伪代码

测试

1.以待排序数组的大小 n=10000 为输入规模,固定 n,随机产生 20 组测试样本,统计不同排序算法在 20 个样本上的平均运行时间;n=20000, n=30000, n=40000, n=50000重复

(1)输入规模n=10000不同排序平均时间(如图6)

(2)输入规模n=20000不同排序平均时间(如图7)

(3)输入规模n=30000不同排序平均时间(如图8)

(4)输入规模n=40000不同排序平均时间(如图9)

(5)输入规模n=50000不同排序平均时间(如图10)

2.不同排序算法在 20 个随机样本的平均运行时间与输入规模 n 的关系(如图12)

3.画出理论效率分析的曲线和实测的效率曲线,注意:由于实测效率是运行时间,而理论效率是基本操作的执行次数,两者需要进行对应关系调整。调整思路:以输入规模为10000 的数据运行时间为基准点,计算输入规模为其他值的理论运行时间,画出不同规模数据的理论运行时间曲线,并与实测的效率曲线进行比较。经验分析与理论分析是否一致?如果不一致,请解释存在的原因。

结论

现在有 1 亿的数据,请选择合适的排序算法与数据结构,在有限的时间内完成进行排序。


写在前面的话

        挺野蛮生长,之前半年打了c语言的题,还没打数据结构的题就直接上算法,只能说是梁静茹给我的勇气了。数据结构只是前几年浅浅过了概念,那时还未入行,虽然作为选修水课通宵搞通概念意外A+。。。(的确真水)。去年边学c边旁听了下,其实啥也也没听进入,emmm不管那么多感觉还能冲,直接上吧。为了拿个满分直接上台pre吧(纯纯被老师批斗也没事),在线忽略伪dalao。

        虽然还一屁股的stm32悬于头上,但也没事整理整理这几个月的战绩吧,当复习了(其实是觉得这博客再荒废下去就废了。。。以后找工作难顶)。

        还是觉得老师一句话还是有点道理的,这算法思维更重要。我作为个纯纯小白过来挑战算法,啥都没学过只能自己想写法子理解消化,求求平安过关别拉绩点~~~

概览

1. 选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理

2. 不同排序算法时间效率的经验分析方法,验证理论分析与经验分析的一致性。

算法原理

        排序问题要求我们按照升序排列给定列表中的数据项,目前为止,已有多种排序算法提出。本实验要求掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理,并进行代码实现。通过对大量样本的测试结果,统计不同排序算法的时间效率与输入规模的关系, 通过经验分析方法,展示不同排序算法的时间复杂度,并与理论分析的基本运算次数做比较, 验证理论分析结论的正确性。

        选择排序(Selection sort是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。

        冒泡排序原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束。

        合并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer的一个非常典型的应用。合并排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。合并排序也叫归并排序。

        快速排序首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边

        插入排序的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

排序算法及伪代码

选择排序

        编程入门就冒泡和选择吧,这2个没啥好说的,实现简单逻辑粗暴(好记哈哈哈)。如果升序,选择排序就是不断挑出剩余最小放到最前面,有点像打牌时我们给牌排序(当然个人习惯这么排)。日常生活也有很多排序我们可以用这种方法。2趟循环实现,时间复杂度O(n^{_{2}})

选择排序伪代码:

SELECTION-SORT(A,n)
for j = 1 to n - 1
    min = A[j]
    k = j
//记录最小数的下标
    for i = j + 1 to n
        if A[i] < min
            min = A[i]
k = i
    A[k] = A[j]
    A[j] = min

冒泡排序

        原理见上。如果升序,剩余最大的数(泡)总会冒到最后,这个通过两两比较交换就可实现。

冒泡排序伪代码:

BUBBLE-SORT(A,n)
for j = 2 to n
    for i = 1 to n – j
        if A[j] > A[j+1]
            swap(A[j],A[j+1])

合并排序

脑洞小故事

        我们可以想象成有一排人想按身高排序。队长收到需要排序的任务。但他觉得自己一个人独自完成这份工作负担是在太重了,时间效率也不高。同时他觉得自己的工作是领导队伍,具体工作应该是下分给下属完成。所以他将人员(包括他自己)从中间一分为二分为2个小队并任命2个小队长,让他们各自先排序下(分治),自己看着2个比较有序的部分还比较好把他们合并再排序。

        而2个小队长怎么排序呢?不难想到他们完全可以用队长的管理方法,继续下分。巡而往复,直到分到每队只有1人那就用排啦,交上去让队长们合并进行排序,并不断上交,直到合并到全队都排好。

效率高吗?

        听起来貌似把事情搞复杂了,相比之下选择算法就更像我们平时排序的法子,不香吗一下子就排好,不用弄得分分合合,搞得更像领导们为了降低自己的工作量把一部分任务丢给下边的人,这么多的交接工作难道不会造成更大的开支吗?

        但其实对于电脑来说效率是很高的,因为电脑不像人那么聪明,用选择排序人是很容易一下子跳出剩余最值。但电脑就麻烦了,它只能一个一个比较,才挑出1个。下次又得遍历全部。想想就知道时间复杂度很高。所以对电脑来说合并排序虽然听起来复杂,但是是很聪明的,比较适合它,相当于把大问题分解小问题,这就是分治思维

合并排序伪代码

        刚才说了过程复杂了很多,而代码实现其实就是用指令对上述过程进行模拟。

MERGE(A,left,right)
mid = (left + right) / 2
for i = left to mid and j = mid+1 to right
    if A[i] < A[j]
        temp[k++] = A[i++]
    else
        temp[k++] = A[j++]
while i <= mid
    temp[k++] = A[i++]
while j <= right
    temp[k++] = A[j++]
while k >= 0
    A[--j] = temp[--k]

MERGE-SORT(A,left,right)
if left < right
    mid = (left + right) / 2
    MERGE-SORT(A,left,mid)
//递归调用
    MERGE-SORT(A,mid+1,right)
    MERGE(A,n,left,right)

快速排序伪代码

        我们可以先以某个标准把数分为大小2堆,对每堆继续分堆,分到最后就排好了。

快速排序伪代码

        标准设为第一个数,降序,小的靠右放,大的靠左放。那么至左找到第一个不符合的小数,至右找到第一个不符合的大数,互相交换。直到2个逼到中间,中间就放标准数。

PARTITION(A,low,high)
pivot = A[low]
//首元素做参考值并记录
while low < high
    while low < right and A[high] >= pivot
        high = high+1
    //从右到左依次找比参考值大的数
    num[low] = num[high]
    while low < right and A[high] >= pivot
        low = low +1
    //从左到右依次找比参考值小的数
    num[high] = num[low]
num[low] = pivot
//中间处放参考值
return low;

QUICK-SORT(A,low,high)
if left < right
    pivot = PARTITION(A,low,high)
    //分割函数整理分类并返回支点下标
    QUICK-SORT(A,low,pivot-1)
    QUICK-SORT(A,pivot+1,high)

插入排序

        给牌排序除了上面说的选择排序的方法,我们还经常可能采取取牌插到已排好序的牌里。自然叫插入排序。

插入排序伪代码

INSERT-SORT(A,n)
for j = 1 to n
    key = A[j]
    //key为待插数
    i = j -1
    for i to 0 and A[i] > key
        A[i + 1] = A[i]
    A[i + 1] = key

测试

1.以待排序数组的大小 n=10000 为输入规模,固定 n,随机产生 20 组测试样本,统计不同排序算法在 20 个样本上的平均运行时间;n=20000, n=30000, n=40000, n=50000重复

以下莫得感情,可以跳过

(1)输入规模n=10000不同排序平均时间(如图6)

选择排序t1 = 0.1325s

冒泡排序t2 = 0.6901s

合并排序t3 = 0.0012s

快速排序t4 = 0.00085s

插入排序t5 = 0.0678s

图表 6  n=10000不同排序平均时间

(2)输入规模n=20000不同排序平均时间(如图7)

选择排序t1 = 0.41825s

冒泡排序t2 = 2.7229s

合并排序t3 = 0.0025s

快速排序t4 = 0.00175s

插入排序t5 = 0.25925s

图表 7  n=20000不同排序平均时间

(3)输入规模n=30000不同排序平均时间(如图8)

选择排序t1 = 0.92415s

冒泡排序t2 = 6.136s

合并排序t3 = 0.004s

快速排序t4 = 0.00275s

插入排序t5 = 0.55435s

图表 8  n=30000不同排序平均时间

(4)输入规模n=40000不同排序平均时间(如图9)

选择排序t1 = 1.60885s

冒泡排序t2 = 10.9242s

合并排序t3 = 0.00545s

快速排序t4 = 0.00385s

插入排序t5 = 0.97275s

图表 9  n=40000不同排序平均时间

(5)输入规模n=50000不同排序平均时间(如图10)

选择排序t1 = 2.5195s

冒泡排序t2 = 17.0636s

合并排序t3 = 0.0069s

快速排序t4 = 0.0049s

插入排序t5 = 1.5176s

图表 10  n=50000不同排序平均时间

算法运行时间
数据规模n1000020000300004000050000
选择排序0.13250.418250.924151.608852.5195
冒泡排序0.69012.72296.13610.924217.0636
合并排序0.00120.0025

0.004

0.005450.0069
快速排序0.000850.001750.002750.003850.0049
插入排序0.06780.259250.554350.972751.5176

图表 11  5种算法平均用时统计(单位:秒)

2.不同排序算法在 20 个随机样本的平均运行时间与输入规模 n 的关系(如图12

图表 12  时间效率与输入规模 n 的关系图

3.画出理论效率分析的曲线和实测的效率曲线,注意:由于实测效率是运行时间,而理论效率是基本操作的执行次数,两者需要进行对应关系调整。调整思路:以输入规模为10000 的数据运行时间为基准点,计算输入规模为其他值的理论运行时间,画出不同规模数据的理论运行时间曲线,并与实测的效率曲线进行比较。经验分析与理论分析是否一致?如果不一致,请解释存在的原因。

答: 选择排序、冒泡排序、插入排序的时间复杂度都是O(n2),那么n=10000,n=20000, n=30000, n=40000, n=50000的理论运行时间比应该是100002 : 200002 : 300002 : 400002 : 500002 , 即1 : 4 : 9 : 16 : 25;

则以输入规模为10000 的数据运行时间为基准点,即参照输入规模n=10000不同排序平均时间——选择排序t1 = 0.1325s,冒泡排序t2 = 0.6901s,插入排序t5 = 0.0678s,可得以下理论效率数据:(如图13-15)

选择排序理论和实际运行时间
数据规模1000020000300004000050000
实际0.13250.418250.924151.608852.5195
理论0.13250.531.19252.123.3125

图表 13 选择排序理论和实测用时(单位:秒)

冒泡排序1000020000300004000050000
实际0.69012.72296.13610.924217.0636
理论0.69022.76046.210911.041617.2525

图表 14 冒泡排序理论和实测用时(单位:秒)

插入排序理论与实际时间
数据规模n1000020000300004000050000
实际0.06780.259250.554350.972751.5176
理论0.06780.27120.61021.08481.695

图表 15  插入排序理论和实测用时(单位:秒)

同理合并排序、快速排序的时间复杂度都是O(nlog2n),那么n=10000,n=20000, n=30000, n=40000, n=50000的理论运行时间比应该是10000log210000 : 20000log220000 : 30000log230000 : 40000log240000 : 50000log250000 ,即1 : (0.5lg2+2) : (0.75lg3+3) : (2lg2+4) : (1.25lg5+5)

则以输入规模为10000 的数据运行时间为基准点,即参照输入规模n=10000不同排序平均时间——合并排序t3 = 0.0012s,快速排序t4 = 0.00085s,可得以下理论效率数据(不完全以n=10000,做了部分优化):(如图16-17)

合并排序理论和实际运行时间
数据规模1000020000300004000050000
实际1.22.545.456.9
理论1.22.584.035.527.05

图表 16  合并排序理论和实测用时(单位:毫秒)

快速排序理论与实际时间
数据规模1000020000300004000050000
实际0.831.752.753.854.9
理论0.831.782.793.824.88

图表 17  快速排序理论和实测用时(单位:毫秒)

    由图表基本可见,经验分析与理论分析基本一致。

结论

    由上述实验过程可见,选择排序算法、冒泡排序算法和插入排序算法的时间复杂度为O(n2), 这意味着用该类算法,数据规模大到一定程度时,其运行时间将很大,时间的增长会随着数据成平方增长。 这对于大数据处理是比较不友好的。该类算法也是较为初期的排序算法,写法简单,逻辑易懂,但算力性价比不高,不适用于数据量较大时使用。

而合并排序算法和快速排序算法采用了采用分治法、递归的方法,将时间复杂度降为O(nlogn)。这在大数据排序的时候,就会比之前的算法有很大的优势。 比如在本次实验中将数据量提到5万的时候,该类算法运行时间仍在几毫秒左右,而上面的3种算法运行时间已经到达十几秒左右,效率相差已经到达万倍。该类算法的运行时间不会像上面的算法受数据增加的影响巨大,而是随着数据的增加,运行时间渐近线性的增加。但注意理论上快速排序的空间复杂度较高为O(n),且最坏情况时时间复杂度也达到了O(n2),运行时间结果变化较大,需要根据现实需求选择合适的算法。但现实中经过实际测试中它的效率很高,而一般空间是足够的,所以快速算法也较为常用。

所以综上,当面临巨大数据量的排序的时候,还是优先选择合并排序算法和快速排序算法。而选择排序算法、冒泡排序算法和插入排序算法不太适用于大数据排序。

现在有 1 亿的数据,请选择合适的排序算法与数据结构,在有限的时间内完成进行排序。

数据量较大,我选用了合并排序算法和快排(c++sort()函数),合并排序算法用时平均t1 = 18.6647s , 快排t2 = 39.8782s(如图18) 。从结果看出,合并算法的效率更高。

 

图表 18 1亿数据合并排序用时平均t1 = 18.6647s , 快排t2 = 39.8782

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
算法设计与分析 作者-王红梅 出版社-清华大学出版社 出版日期-07 1 2006. 共262页 目录 第 1 章 绪论 1 .1 算法的基本概念 1 . 1 . 1 为什么要学习算法 1 . 1 . 2 算法及其重要特性 1 . 1 . 3 算法的描述方法 1 . 1 . 4 算法设计的一般过程 1 . 1 . 5 重要的问题类型 1 .2 算法分析 1 . 2 . 1 渐进符号 1 . 2 . 2 最好、 最坏和平均情况 1 . 2 . 3 非递归算法分析 1 . 2 . 4 递归算法分析 1 . 2 . 5 算法的后验分析 1 .3 实验项目— — —求最大公约数 阅读材料— — —人工神经网络与 BP 算法 习题 1 第 2 章 NP 完全理论 2 .1 下界 2 . 1 . 1 平凡下界 2 . 1 . 2 判定树模型 2 . 1 . 3 最优算法 2 .2 算法的极限 2 . 2 . 1 易解问题与难解问题 2 . 2 . 2 实际问题难以求解的原因 2 . 2 . 3 不可解问题 2 .3 P 类问题和 NP 类问题 2 .3 .1 判定问题 2 .3 .2 确定性算法与 P 类问题 2 .3 .3 非确定性算法与 NP 类问题 2 .4 NP 完全问题 2 .4 .1 问题变换与计算复杂性归约 2 .4 .2 NP 完全问题的定义 2 .4 .3 基本的 NP 完全问题 2 .4 .4 NP 完全问题的计算机处理 2 .5 实验项目— — —SAT 问题 阅读材料— — —遗传算法 习题 2 第 3 章 蛮力法 3 .1 蛮力法的设计思想 3 .2 查找问题中的蛮力法 3 .2 .1 顺序查找 3 .2 .2 串匹配问题 3 .3 排序问题中的蛮力法 3 .3 .1 选择排序 3 .3 .2 起泡排序 3 .4 组合问题中的蛮力法 3 .4 .1 生成排列对象 3 .4 .2 生成子集 3 .4 .3 0 / 1 背包问题 3 .4 .4 任务分配问题 3 .5 图问题中的蛮力法 3 .5 .1 哈密顿回路问题 3 .5 .2 TSP 问题 3 .6 几何问题中的蛮力法 3 .6 .1 最近对问题 3 .6 .2 凸包问题 3 .7 实验项目— — —串匹配问题 阅读材料— — —蚁群算法 习题 3 第 4 章 分治法 4 .1 概述 4 .1 .1 分治法的设计思想 4 .1 .2 分治法的求解过程 4 .2 递归 4 .2 .1 递归的定义 4 .2 .2 递归函数的运行轨迹 4 .2 .3 递归函数的内部执行过程 4 .3 排序问题中的分治法 4 .3 .1 归并排序 4 .3 .2 快速排序 4 .4 组合问题中的分治法 4 .4 .1 最大子段和问题 4 .4 .2 棋盘覆盖问题 4 .4 .3 循环赛日程安排问题 4 .5 几何问题中的分治法 4 .5 .1 最近对问题 4 .5 .2 凸包问题 4 .6 实验项目— — —最近对问题 阅读材料— — —鱼群算法 习题 4 第 5 章 减治法 5 .1 减治法的设计思想 5 .2 查找问题中的减治法 5 .3 排序问题中的减治法 5 .4 组合问题中的减治法 5 .5 实验项目— — —8 枚硬币问题 阅读材料— — —粒子群算法 习题 5 第 6 章 动态规划法 6 .1 概述 6 .2 图问题中的动态规划法 6 .3 组合问题中的动态规划法 6 .4 查找问题中的动态规划法 6 .5 实验项目— — —最大子段和问题 阅读材料— — —文化算法 习题 6 第 7 章 贪心法 7 .1 概述 7 .2 图问题中的贪心法 7 .3 组合问题中的贪心法 7 .4 实验项目— — —霍夫曼编码 阅读材料— — —模拟退火算法 习题 7 第 8 章 回溯法 8 .1 概述 8 .2 图问题中的回溯法 8 .3 组合问题中的回溯法 8 .4 实验项目— — —0/ 1 背包问题 阅读材料— — —禁忌搜索算法 习题 8 第 9 章 分支限界法 9 .1 概述 9 .2 图问题中的分支限界法 9 .3 组合问题中的分支限界法 9 .4 实验项目— — —电路布线问题 阅读材料— — —免疫算法 习题 9 第 10 章 概率算法 10 .1 概述 10 .1 .1 概率算法的设计思想 10 .1 .2 随机数发生器 10 .2 舍伍德(Sherwood)型概率算法 10 .2 .1 快速排序 10 .2 .2 选择问题 10 .3 拉斯维加斯( Las Vegas)型概率算法 10 .3 .1 八皇后问题 10 .3 .2 整数因子分解问题 10 .4 蒙特卡罗(Monte Ca rlo)型概率算法 10 .4 .1 主元素问题 10 .4 .2 素数测试问题 10 .5 实验项目— — —随机数发生器 阅读材料— — —DNA 计算与 DNA 计算机 习题 10 第 11 章 近似算法 11 .1 概述 11 .1 .1 近似算法的设计思想 11 .1 .2 近似算法性能 11 .2 图问题中的近似算法 11 .2 .1 顶点覆盖问题 11 .2 .2 TSP 问题 11 .3 组合问题中的近似算法 11 .3 .1 装箱问题 11 .3 .2 子集和问题 11 .4 实验项目— — —TSP 问题的近似算法 阅读材料— — —量子密码技术 习题 11 第 12 章 计算复杂性理论 12 .1 计算模型 12 .1 .1 图灵机的基本模型 12 .1 .2 k 带图灵机和时间复杂性 12 .1 .3 离线图灵机和空间复杂性 12 .2 P 类问题和 NP 类问题 12 .2 .1 非确定性图灵机 12 .2 .2 P 类语言和 NP 类语言 12 .3 NP 完全问题 12 .3 .1 多项式时间变换 12 .3 .2 Cook 定理 12 .4 实验项目— — —NP 完全问题树 阅读材料— — —算法优化策略

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jennie佳妮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值