《大話數據結構》中對算法的時間複雜度定義以下:算法
「算法分析時,語句的總執行次數T[n]是關於問題規模n的函數,進而分析T[n]隨n的變化狀況並肯定T[n]的數量級。算法的時間複雜度,也就是算法的時間度量,記作T[n]=O(f[n]),表示隨問題規模n的增大,算法的執行時間的增加率和f[n]的增加率相同,稱作算法的漸進時間複雜度,簡稱時間複雜度,f[n]是問題規模n的某個函數。」編程
根據定義舉個例子,計算1+2+3+4+···+100 = ?數據結構
int sum = 0 ,n=100;函數
for(int i=1;i<=n;i++){工具
sum+=i;blog
}數學
算法執行完畢時,語句的總執行次數T[n] = 1+n+1+n = 2n+2,隨着問題規模n的增大,算法的執行時間的增加率和f[n]的增加率相同,其中f[n] = 2n,由於隨着n的增大,常數2並不增大,爲了簡化計算,取主要的執行次數2n,這樣的話T[n] = O(2n)。 也就是O(n) 【下文解釋爲何去掉2】bfc
同一個問題,咱們使用高斯的算法解決。循環
int sum = 0,n = 100;im
sum = (n*(n+1))/2;
算法執行完畢時,語句總執行次數爲2,T[n]=O(2)。也就是O(1)【下文解釋】
經過以上例子,給出「大O階」的推倒(ノ*・ω・)ノ 步驟:
1.計算語句總執行次數得出f[n]
2.用常數1取代運行此書中的全部加法常數
3.在修改後的運行次數函數中,只保留最高階項
4.若是最高階項存在且不是1,去除於這個項相乘的常數
再舉個例子
int n=100;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
n--;
}
}
printf("n=%d",n);
第一句很明顯執行1次,嵌套循環的執行次數一眼看不出來,這就須要分析了,先看內循環,j自增一次,n自減一次,能夠推測當n自減到n/2時,第一次內循環結束,此時第二句執行了一次。接下來看第二次內循環,當n減到n/4的時候,第二次內循環結束,第二句執行了第二次。由此可知,當i>=n/(2i)時,外循環也就是第二句結束,也就是說外循環最多運行n/(2i)次,當n等於一百萬的時候,i等於16,因此外循環能夠忽略不計,內循環 n--; 執行了n-n/(2i)次,約等於n次。因此這個例子的算法時間複雜度爲O(n)。
上面那個例子是我本身編的。最開始計算外層循環的時候也迷糊了,在羣裏和你們討論了才明白,這也告訴咱們,計算複雜度的時候,必定要有全局觀,不要死磕每一句的執行次數。今早在看《編程珠璣》時,瞭解了近似估算,發現也能夠用在這個地方。
最後給出各類複雜度的圖像,繪圖工具使用的是Mathematica,感受是比Matlab更好用的數學工具。
刪除幾個增加率快的