关于复杂度:常见排序算法及复杂度

1. 常见算法复杂度大O加上()的模式,外面其实包裹的是一个函数f(),O(f()),指明某个算法的 “耗时/耗空间”与“数据增长量”之间的关系。其中的 n代表输出数据的量。 1.1. O(1)1. 解释最低复杂度,常量值。也就是 “耗时/耗空间” 与 “数据增长量” 无关,无论输出数据增大多少倍,“耗时/耗空间” 都不变。 2. 举例哈希算法就是典型的 O(1)工夫复杂度算法,例如 HashMap、布隆过滤器等哈希算法的利用,无论数据规模多大,在计算出 hash key 的值之后,都能够一次性找到指标(不思考哈希抵触的话)。 1.2. O(n)1. 解释数据量增大几倍,耗时也增大几倍。 2. 举例例如:最常见的遍历算法,遍历一次所有值,找出其中的最大值。 1.3. O(n^2)1. 解释对n个数排序,须要扫描 n^2次。 2. 举例例如:冒泡排序法、抉择排序法等。因为该算法都是2层循环,第一层循环遍历 n-1 趟,第二层循环遍历 n-i 趟(i递增)。 1.4. O(logn)1. 解释当数据增大n倍时,耗时增大logn倍。 这里 log 是以2为底。比方:log256=8 2. 举例二分查找法就是 O(logn) 的算法,每找一次就排除个别的可能性,256条数据中只需查找8次就能够。 1.5. O(nlogn)1. 解释当数据增大n倍时,耗时增大 n乘以logn 倍。例如当数据增大256倍,耗时增大 256*8 倍。 这个复杂度高于线性O(n),低于平方O(n^2)。 2. 举例归并排序法、疾速排序法的工夫复杂度就是 O(nlogn)。 2. 排序算法复杂度网上看到这张图: 2.1. 冒泡排序为啥 O(n^2)冒泡排序法遍历的次数: 总层数:n−1每层遍历次数:n−i(i在 1 ~ n 递增)可基于 ∑i 求和,计算出总次数:n(n−1)/2=n^2/2 - n/2既然是 n^2/2 - n/2,为什么说工夫复杂度是 O(n^2) 呢?因为咱们常说的复杂度不是精确的值,而是当数据量收缩时,随之工夫收缩的模型。当 n 趋向于无限大时,n^2/2 - n/2 也就趋向于 n^2。 ...

April 26, 2023 · 2 min · jiezi

关于复杂度:复杂度分析如何分析统计算法的执行效率和资源消耗

作者:京东物流 崔旭 咱们都晓得,数据结构和算法自身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间。所以,执行效率是算法一个十分重要的考量指标。那如何来掂量你编写的算法代码的执行效率呢?这里就要用到咱们明天要讲的内容:工夫、空间复杂度剖析。 1 为什么须要复杂度剖析?你可能会有些纳闷,我把代码跑一遍,通过统计、监控,就能失去算法执行的工夫和占用的内存大小。为什么还要做工夫、空间复杂度剖析呢?这种分析方法能比实实在在跑一遍失去的数据更精确吗? 首先能够必定地说,这种评估算法执行效率的办法是正确的。很多数据结构和算法书籍还给这种办法起了一个名字,叫预先统计法。然而,这种统计办法有十分大的局限性。 1.1 测试后果十分依赖测试环境测试环境中硬件的不同会对测试后果有很大的影响。比方,咱们拿同样一段代码,别离用 Intel Core i9 处理器和 Intel Core i3 处理器来运行,i9 处理器要比 i3 处理器执行的速度快很多。还有,比方本来在这台机器上 a 代码执行的速度比 b 代码要快,等咱们换到另一台机器上时,可能会有截然相同的后果。 1.2 测试后果受数据规模的影响很大对同一个排序算法,待排序数据的有序度不一样,排序的执行工夫就会有很大的差异。极其状况下,如果数据曾经是有序的,那排序算法不须要做任何操作,执行工夫就会十分短。除此之外,如果测试数据规模太小,测试后果可能无奈实在地反馈算法的性能。比方,对于小规模的数据排序,插入排序可能反倒会比疾速排序要快! 所以,咱们须要一个不必具体的测试数据来测试,就能够粗略地预计算法的执行效率的办法,这就是咱们接下来要说的大O复杂度表示法。 2 大O复杂度表示法算法的执行效率,粗略地讲,就是算法代码执行的工夫。然而,如何在不运行代码的状况下,用“肉眼”失去一段代码的执行工夫呢? 这里有段非常简单的代码,求 1,2,3…n 的累加和。当初,一块来估算一下这段代码的执行工夫吧。 从 CPU 的角度来看,这段代码的每一行都执行着相似的操作:读数据-运算-写数据。只管每行代码对应的 CPU 执行的个数、执行的工夫都不一样,然而,咱们这里只是粗略预计,所以能够假如每行代码执行的工夫都一样,为 unit_time。在这个假如的根底之上,这段代码的总执行工夫是多少呢? 第 2、3 行代码别离须要 1 个 unit\_time 的执行工夫,第 4、5 行都运行了 n 遍,所以须要 2n\_unit\_time 的执行工夫,所以这段代码总的执行工夫就是 (2n+2)\_unit_time。能够看进去,所有代码的执行工夫 T(n) 与每行代码的执行次数成正比。 依照这个剖析思路,咱们再来看这段代码。 咱们仍旧假如每个语句的执行工夫是 unit_time。那这段代码的总执行工夫 T(n) 是多少呢? 第 2、3、4 行代码,每行都须要 1 个 unit\_time 的执行工夫,第 5、6 行代码循环执行了 n 遍,须要 2n\_unit\_time 的执行工夫,第 7、8 行代码循环执行了 n²遍,所以须要 2n²\_unit\_time 的执行工夫。所以,整段代码总的执行工夫 T(n) = (2n²+2n+3)*unit\_time。 ...

March 21, 2023 · 2 min · jiezi