为什么算法渐进复杂度中对数的底数总为2
在分析各種算法時,經常看到O(log2n)O(log2?n)或O(nlog2n)O(nlog2?n)這樣的漸進復雜度。不知有沒有同學困惑過,為什么算法的漸進復雜度中的對數都是以2為底?為什么沒有見過O(nlog3n)O(nlog3?n)這樣的漸進復雜度?本文解釋這個問題。
三分式歸并排序的時間復雜度
先看一個小例子。
大多數人應該對歸并排序(merge sort)很熟悉,它的漸進復雜度為O(nlog2n)O(nlog2?n)。那么如果我們將歸并排序改為均分成三份而不是兩份,其算法時間復雜度是否有變化呢?
遞歸分析
下面通過遞歸分析對三分式歸并排序的時間復雜度進行分析。因為不管是三分還是二分,對于總共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(nlog3?n)。如下圖所示:
對數的陷阱
那么這是否意味著三分式歸并排序在時間復雜度上要優于二分式的歸并排序呢?因為直覺上nlog3nnlog3?n比nlog2nnlog2?n要優一些。
實際上三分式歸并排序的時間復雜度確實是T(n)=O(nlog3n)T(n)=O(nlog3?n),而且同時也是T(n)=O(nlog2n)T(n)=O(nlog2?n)。
這看起來似乎是矛盾的,nlog3nnlog3?n和nlog2nnlog2?n當然在絕大多數情況下是不相等的,但是在漸進復雜度情況下就不同了,因為漸進復雜度是忽略常系數的,但是似乎也看不出來nlog3nnlog3?n和nlog2nnlog2?n是差一個常系數。關鍵就在于我們應該在中學學過的一個東西:對數換底公式。
logab=logcblogcaloga?b=logc?blogc?a
其中a和c均大于0且不等于1。
根據換底公式可以得出:
log3n=log2nlog23log3?n=log2?nlog2?3
所以nlog3nnlog3?n比nlog2nnlog2?n只差一個常系數1log231log2?3。因此,從漸進時間復雜度看,三分式歸并并不比二分式歸并更優,當然還是有個常系數的差別的。
更一般的:
logan=log2nlog2aloga?n=log2?nlog2?a
因此對于大于1的a來說,都與O(log2n)O(log2?n)差一個常系數而已,因此為了簡便,一般都用O(log2n)O(log2?n)表示對數的漸進復雜度,這就解決了本文初始的疑問。當然,以任何大于1的a為底數都是沒有問題的。
from:?http://blog.codinglabs.org/articles/why-logarithm-base-of-asymptotic-time-complexity-always-two.html
總結
以上是生活随笔為你收集整理的为什么算法渐进复杂度中对数的底数总为2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法分析中递推式的一般代数解法
- 下一篇: 聊聊如何检测素数