二分检索用途及复杂性_二分查找和三分查找哪个快?算法复杂度与常数无关?复杂度分析的常见误区...

还记得两三年前,我初看一本算法书,看到二分查找算法的复杂度时,我发现了了不得的东西:二分查找每次查询范围减少一半,需要查询的次数是

equation?tex=log_2n ,它的复杂度是

equation?tex=log_2n

我把它改成三分查找,每次查询两个数字与我的目标数字比较,那么我就可以把查询范围缩小成原先的 1 / 3。那这样我需要的查询次数就只有

equation?tex=log_3n ,复杂度也是

equation?tex=log_3n ,一下子就优化了这么多!

那如果是四分,五分,六分,七分,岂不是能无限优化到

equation?tex=log_4n%2Clog_5n%2Clog_6n%5Cdots ?我要成为算法科学家啦!

当然,我的想法是错的。但是,我错在哪里呢?为什么三分的复杂度看起来低了,但是却没有人用?好了,正文开始。

要理解这个问题,首先要知道算法的复杂度到底如何确定。什么时候我们认为一个算法的复杂度高于另一个算法?什么时候两个算法的复杂度其实是一样的?

对于大部分算法来说,当规模

equation?tex=n 趋于无穷大时,问题的求解时间都会趋于无穷大。那么你说的这个无穷大,它到底有多大?复杂度的记法,我们当然都知道使用大

equation?tex=O 或者大

equation?tex=%5CTheta 。但是,这两个符号,到底比较的是什么?这就是这篇文章首先要回答的问题。

一句话答案,我们所说的算法复杂度的大小,其实是算法复杂度的无穷大的阶数。

也就是说,如果一个算法 A 的复杂度的无穷大阶数比另一个算法 B 的无穷大阶数小,也就是说

equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7BT_A%28n%29%7D%7BT_B%28n%29%7D%3D0 ,那么此时 A 的复杂度更小。下面举几个例子:equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7Bn%7D%7Bn%5E2%7D%3D0 ,所以

equation?tex=%5CTheta%28n%29 的算法比

equation?tex=%5CTheta%28n%5E2%29 的算法更优

equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7Blog_2n%7D%7Bn%7D%3D0 ,所以

equation?tex=%5CTheta%28log_2n%29 的算法比

equation?tex=%5CTheta%28n%29 的算法更优

但是如果一个算法的复杂度函数比另一个算法的复杂度函数小,但他俩的无穷大阶数一样,那么其实两个算法的复杂度是一样的。这里也有几个例子:equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7B2n%7D%7Bn%7D%3D2 ,2 是常数。所以

equation?tex=%5CTheta%282n%29 的算法与

equation?tex=%5CTheta%28n%29 的算法复杂度一样

equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7Bn%5E2%7D%7B%28%5Cfrac%7Bn%7D%7B2%7D%29%5E2%7D%3D4 ,4 是常数。所以

equation?tex=%5CTheta%28n%5E2%29 的算法与

equation?tex=%5CTheta%28%28%5Cfrac+n+2%29%5E2%29 的算法复杂度一样

好了,我们已经知道如何比较两个算法复杂度了。现在我们来看看为什么三分不比二分快。

答案很简单:二分法和三分法的渐进复杂度是一样的。

二分法的渐进复杂度为

equation?tex=log_2n ,三分法的渐进复杂度为

equation?tex=log_3n ,这两个复杂度都没有问题。那为什么说这两个是一样的呢?

equation?tex=log_3n 看起来就是比

equation?tex=log_2n 小,而且算出来也确实小很多啊?

Talk is cheap,让我们直接来比较一下它们的无穷大阶数:

equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7B%5Clog_2n%7D%7B%5Clog_3n%7D%3D%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7B%5Cfrac%7B%5Cln+n%7D%7B%5Cln2%7D%7D%7B%5Cfrac%7B%5Cln+n%7D%7B%5Cln3%7D%7D%3D%5Cfrac%7B%5Cln3%7D%7B%5Cln2%7D%3D%5Clog_2+3

equation?tex=log_23 是个常数,因此,两个函数是同阶无穷大。二分法和三分法的渐进复杂度其实是一样的。

这个结论也可以推广一下。任意取两个对数函数

equation?tex=log_an

equation?tex=log_bn ,比较它们的无穷大阶数都会得到

equation?tex=log_ab ,是个常数。因此对数函数的底对于算法的复杂度分析是没有意义的。

因此,无论是二分法,三分法,四分法,五分法...复杂度都是一样的,分的越多,代码反而越复杂,提高你的人脑处理复杂度,不值不值。

那么,这么看来,

equation?tex=2n

equation?tex=n 是一样的,

equation?tex=%5Clog_2n

equation?tex=log_3n 是一样的。那算法复杂度分析时,常数都不重要吗?

并不是。

最常见的反例,

equation?tex=n%5E2

equation?tex=n%5E3 显然复杂度不同。因为

equation?tex=%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7Bn%5E2%7D%7Bn%5E3%7D%3D%5Clim_%7Bn%5Crightarrow+%5Cinfty%7D%5Cfrac%7B1%7D%7Bn%7D%3D0

equation?tex=n%5E2 是更低阶的无穷大。

当然,大部分人可能不会在

equation?tex=n%5E2

equation?tex=n%5E3 的比较上犯错误,但是下面这个比较,错的人就不少了。

equation?tex=2%5En

equation?tex=3%5En 哪个复杂度更大?

很多人以为这两个复杂度是一样的,因为常数不在指数位置上,看起来只是不同的常数做了指数操作,而常数一般对算法的复杂度没有影响。

但是实际上

equation?tex=%5Clim_%7Bn%5Crightarrow%5Cinfty%7D%5Cfrac%7B2%5En%7D%7B3%5En%7D%3D%5Clim_%7Bn%5Crightarrow%5Cinfty%7D%28%5Cfrac2+3%29%5En%3D0

equation?tex=2%5En 的无穷大阶数比

equation?tex=3%5En 要小。这两者复杂度并不一样。

而有人可能还觉得,就算复杂度不一样,可能也差不太多吧?都是指数函数,本身复杂度已经很高了啊?

但是实际上并不是这样。我们可以把

equation?tex=n%5E2

equation?tex=n%5E3

equation?tex=2%5En

equation?tex=3%5En 放到一起比较一下。

equation?tex=n%5E3 相对于

equation?tex=n%5E2 ,很多人已经认为是增长了太多,不太能接受了。那么

equation?tex=3%5En 相对于

equation?tex=2%5En 增长了多少呢?我们其实可以比较一下这两个“增长”之间的无穷大阶数。

equation?tex=%5Clim_%7Bn%5Crightarrow%5Cinfty%7D%5Cfrac%7B%5Cfrac%7Bn%5E3%7D%7Bn%5E2%7D%7D%7B%5Cfrac%7B3%5En%7D%7B2%5En%7D%7D%3D%5Clim_%7Bn%5Crightarrow%5Cinfty%7D%5Cfrac+n%7B%28%5Cfrac+3+2%29%5En%7D%3D0

可见,equation?tex=n%5E3

equation?tex=n%5E2 差,但是它们之间相差的时间倍数只是在线性增长。而

equation?tex=3%5En 相对于

equation?tex=2%5En ,相差的则更多,它们之间相差的时间倍数还是在指数增长!

这是什么概念呢?

如果有一个问题规模为

equation?tex=n%3D20

equation?tex=n%5E2 算法可以用 1 秒解决,那么使用

equation?tex=n%5E3 的算法,你需要 20 秒才能解决。这已经让大部分人无法接受了。

但是,如果有一个问题规模为

equation?tex=n%3D20

equation?tex=2%5En 算法可以用 1 秒解决,那么使用

equation?tex=3%5En 的算法,你需要 3325 秒才能解决!

所以,你现在还觉得,

equation?tex=2%5En

equation?tex=3%5En 差不多吗?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值