本篇博文非博主原創,系通過度娘收集整理而來,如有雷同,請聯系博主,追加上轉載出處。同時博主水平和理解有限,如有什么偏差請廣大博友指定。
學習交流qq:792911374
時間復雜度
同一問題可用不同算法解決,而一個算法的質量優劣將影響到算法乃至程序的效率。一個算法的時間開銷記作:T(n),其中n表示算法的基本操作模塊被重復執行的次數。算法的時間復雜度記做T(n)=O(f(n)),隨着n的增大,算法執行時間的增長率和f(n)的增長率成正比,所以f(n)越小,算法的時間復雜度越低,算法的效率越高。時間復雜度常用大O符號表述。這種用大寫的O來代表算法的時間復雜度的記法叫"大O階"記法。
算法的時間復雜度(大O階)的計算方法為:
1、用常數1取代運行時間中的所有加法常數。
2、在修改后的運行次數函數中,只保留高階項。
3、如果最高階項存在且不是1,則去除與這個項相乘的常數。
也就是當n增大到一定值后,對時間復雜度影響最大的就是n的冪次最高的項,其他的常數項和低冪次項都可以忽略不計。
例如:
在計算時間復雜度的時候,先找出算法的基本操作,然后根據相應的各語句確定它的執行次數。例如:
1 int n = 100000; //執行了1次 2 for(int i = 0; i < n; i++){ //執行了n+1次 3 for(int j = 0; j < n; j++) //執行了n*(n+1)次 4 { 5 printf("i = %d, j = %d", i, j); //執行了n*n次 6 } 7 } 8 9 for(int i = 0; i < n; i++){ //執行了n+1次 10 printf("i = %d", i); //執行了n次 11 } 12 13 printf("Done"); //執行了1次
按上面推導"大O階"的步驟我們先來第一步:"用常數1取代運行時間中的所有加法常數",則上面的算式變為:
執行總次數 = 2n^2 + 3n + 1;
第二步:"在修改后的運行次數函數中,只保留最高階項",這里的最高階項是n的二次方
所以算式變為:
執行總次數 = 2n^2;
第三步:"如果最高階項存在且不是1,則去除與這個項相乘的常數",這里n的二次方不是1所以
要去除這個項相乘的常數算式變為:
執行總次數 = n^2;
因此,最后我們得到上面的那段代碼的算法時間復雜度表示為: O(n^2);
按數量級遞增排列,常見的時間復雜度有:
常數階O(1), 對數階O(log2n),線性階O(n)
線性對數階O(nlog2n), 平方階O(n^2), 立方階O(n^3)..., k次方階O(n^k), 指數階O(2^n),隨着問題規模n的不斷增大,
上述時間復雜度不斷增大,算法的執行效率越低。
如:嵌套一層for循環的時間復雜度為:O(n),二層for循環為O(n^2),二分的算法時間復雜度為:O(logn),如果一個for循環套一個二分,那么時間復雜度為O(nlogn);
備注:這里只是通過一個數理化的形式來比較算法的時間執行效率,並不能真正推導出算法在特定機器的執行時間,這取決於具體的電腦和代碼。
總結:
一個算法所耗費的時間=算法中每條語句的執行時間之和。算法轉換為程序后,每條語句執行一次所需的時間取決於機器的指令性能、速度以及編譯所產生的代碼質量等難以確定的因素。如果要計算一個算法執行所耗費的時間,從理論上是不能算出來的,必須上機運行測試才能知道。
若要獨立於機器的軟、硬件系統來分析算法的時間耗費,則設每條語句執行一次所需的時間均是單位時間,一個算法的時間耗費就是該算法中所有語句的頻度之和(算法中的語句執行次數稱為語句的頻度或時間頻度)。