为什么算法渐进复杂度中对数的底数总为2
2016-01-05 12:58
393 查看
在分析各种算法时,经常看到O(log2n)O(log2n)或O(nlog2n)O(nlog2n)这样的渐进复杂度。不知有没有同学困惑过,为什么算法的渐进复杂度中的对数都是以2为底?为什么没有见过O(nlog3n)O(nlog3n)这样的渐进复杂度?本文解释这个问题。
先看一个小例子。
大多数人应该对归并排序(merge sort)很熟悉,它的渐进复杂度为O(nlog2n)O(nlog2n)。那么如果我们将归并排序改为均分成三份而不是两份,其算法时间复杂度是否有变化呢?
下面通过递归分析对三分式归并排序的时间复杂度进行分析。因为不管是三分还是二分,对于总共n个数据来说,一遍合并的复杂度为O(n)O(n),所以三分式归并排序的递归式为:
T(n)=3T(n/3)+O(n)T(n)=3T(n/3)+O(n)
如果把这个递归式的递归树画出来,很容易得到T(n)=O(nlog3n)T(n)=O(nlog3n)。如下图所示:
![](http://blog.codinglabs.org/uploads/pictures/why-logarithm-base-of-asymptotic-time-complexity-always-two/1.png)
那么这是否意味着三分式归并排序在时间复杂度上要优于二分式的归并排序呢?因为直觉上nlog3nnlog3n比nlog2nnlog2n要优一些。
实际上三分式归并排序的时间复杂度确实是T(n)=O(nlog3n)T(n)=O(nlog3n),而且同时也是T(n)=O(nlog2n)T(n)=O(nlog2n)。
这看起来似乎是矛盾的,nlog3nnlog3n和nlog2nnlog2n当然在绝大多数情况下是不相等的,但是在渐进复杂度情况下就不同了,因为渐进复杂度是忽略常系数的,但是似乎也看不出来nlog3nnlog3n和nlog2nnlog2n是差一个常系数。关键就在于我们应该在中学学过的一个东西:对数换底公式。
logab=logcblogcalogab=logcblogca
其中a和c均大于0且不等于1。
根据换底公式可以得出:
log3n=log2nlog23log3n=log2nlog23
所以nlog3nnlog3n比nlog2nnlog2n只差一个常系数1log231log23。因此,从渐进时间复杂度看,三分式归并并不比二分式归并更优,当然还是有个常系数的差别的。
更一般的:
logan=log2nlog2alogan=log2nlog2a
因此对于大于1的a来说,都与O(log2n)O(log2n)差一个常系数而已,因此为了简便,一般都用O(log2n)O(log2n)表示对数的渐进复杂度,这就解决了本文初始的疑问。当然,以任何大于1的a为底数都是没有问题的。
from: http://blog.codinglabs.org/articles/why-logarithm-base-of-asymptotic-time-complexity-always-two.html
三分式归并排序的时间复杂度
先看一个小例子。大多数人应该对归并排序(merge sort)很熟悉,它的渐进复杂度为O(nlog2n)O(nlog2n)。那么如果我们将归并排序改为均分成三份而不是两份,其算法时间复杂度是否有变化呢?
递归分析
下面通过递归分析对三分式归并排序的时间复杂度进行分析。因为不管是三分还是二分,对于总共n个数据来说,一遍合并的复杂度为O(n)O(n),所以三分式归并排序的递归式为:T(n)=3T(n/3)+O(n)T(n)=3T(n/3)+O(n)
如果把这个递归式的递归树画出来,很容易得到T(n)=O(nlog3n)T(n)=O(nlog3n)。如下图所示:
![](http://blog.codinglabs.org/uploads/pictures/why-logarithm-base-of-asymptotic-time-complexity-always-two/1.png)
对数的陷阱
那么这是否意味着三分式归并排序在时间复杂度上要优于二分式的归并排序呢?因为直觉上nlog3nnlog3n比nlog2nnlog2n要优一些。实际上三分式归并排序的时间复杂度确实是T(n)=O(nlog3n)T(n)=O(nlog3n),而且同时也是T(n)=O(nlog2n)T(n)=O(nlog2n)。
这看起来似乎是矛盾的,nlog3nnlog3n和nlog2nnlog2n当然在绝大多数情况下是不相等的,但是在渐进复杂度情况下就不同了,因为渐进复杂度是忽略常系数的,但是似乎也看不出来nlog3nnlog3n和nlog2nnlog2n是差一个常系数。关键就在于我们应该在中学学过的一个东西:对数换底公式。
logab=logcblogcalogab=logcblogca
其中a和c均大于0且不等于1。
根据换底公式可以得出:
log3n=log2nlog23log3n=log2nlog23
所以nlog3nnlog3n比nlog2nnlog2n只差一个常系数1log231log23。因此,从渐进时间复杂度看,三分式归并并不比二分式归并更优,当然还是有个常系数的差别的。
更一般的:
logan=log2nlog2alogan=log2nlog2a
因此对于大于1的a来说,都与O(log2n)O(log2n)差一个常系数而已,因此为了简便,一般都用O(log2n)O(log2n)表示对数的渐进复杂度,这就解决了本文初始的疑问。当然,以任何大于1的a为底数都是没有问题的。
from: http://blog.codinglabs.org/articles/why-logarithm-base-of-asymptotic-time-complexity-always-two.html
相关文章推荐
- 网络路由技术及运用2
- 获取免费的Camtasia Studio 2使用授权
- 选择模式 - XSL教程 - 2
- JS Common 2 之比较常用到的函数第1/3页
- 在C语言中使用对数函数的方法
- 让Sublime Text 2支持GB2312和GBK编码
- 野人过河问题
- Video 5 Part 2 计算子网
- 诺基亚N8
- Sublime Text 2 快捷键用法大全
- 四个人过桥分别用时1、2、5、10,每次最多两个人过桥,只有一把手电,求时间最短
- 2
- CentOS /usr/libexec/gconf-sanity-check-2 exited with status 256问题解决
- 关于Linux实时性能的研究及测试 2
- init 0-6 (启动级别:init 0,1,2,3,4,5,6)
- programming language
- (2)开始构建:一个基本的应用--ZF2官方教程译文
- iOS cocos2d 2游戏开发实战(第3版)
- 一、struts 2 基础---3.struts.xml的配置
- Struts 2 学习(一) 环境配置