【對於乙個給定的演算法,通常要評估其正確性和執行效率的高低。演算法的正確性評估不在本文範圍之內,本文主要討論從演算法的時間複雜度特性去評估演算法的優劣。】
如何衡量乙個演算法的好壞呢?
顯然,選用的演算法應該是正確的(演算法的正確性不在此論述)。除此之外,通常有三個方面的考慮:
(1)演算法在執行過程中所消耗的時間;
(2)演算法在執行過程中所佔資源的大小,例如,占用記憶體空間的大小;
(3)演算法的易理解性、易實現性和易驗證性等等。
本文主要討論演算法的時間特性,並給出演算法在時間複雜度上的度量指標。
在各種不同的演算法中,若演算法語句的執行次數為常數,則演算法的時間複雜度為o(1),按數量級遞增排列,常見的時間複雜度量有:
(1)o(1):常量階,執行時間為常量
(2)o(logn):對數階,如二分搜尋演算法
(3)o(n):線性階,如n個數內找最大值
(4)o(nlogn):對數階,如快速排序演算法
(5)o(n^2):平方階,如選擇排序,氣泡排序
(6)o(n^3):立方階,如兩個n階矩陣的乘法運算
(7)o(2^n):指數階,如n個元素集合的所有子集的演算法
(8)o(n!):階乘階,如n個元素全部排列的演算法
下圖給出了隨著n的變化,不同量級的時間複雜度變化曲線。
複雜度102050100100010000100000
o(1)
<1s
<1s
<1s
<1s
<1s
<1s
<1s
o(log2(n))
<1s
<1s
<1s
<1s
<1s
<1s
<1s
o(n)
<1s
<1s
<1s
<1s
<1s
<1s
<1s
o(n*log2(n))
<1s
<1s
<1s
<1s
<1s
<1s
<1s
o(n2)
<1s
<1s
<1s
<1s
<1s
2s3-4 min
o(n3)
<1s
<1s
<1s
<1s
20s5 hours
231 days
o(2n)
<1s
<1s
260 days
hangs
hangs
hangs
hangs
o(n!)
<1s
hangs
hangs
hangs
hangs
hangs
hangs
o(nn)
3-4 min
hangs
hangs
hangs
hangs
hangs
hangs
評估演算法時間複雜度的具體步驟是:
(1)找出演算法中重複執行次數最多的語句的頻度來估算演算法的時間複雜度;
(2)保留演算法的最高次冪,忽略所有低次冪和高次冪的係數;
(3)將演算法執行次數的數量級放入大ο記號中。
以下對常見的演算法時間複雜度度量進行舉例說明:
(1)o(1):常量階,操作的數量為常數,與輸入的資料的規模無關。n = 1,000,000 -> 1-2 operations
temp=a;
a=b;
b=temp;
用常數1來取代執行時間中所有加法常數;上面語句共三條操作,單條操作的頻度為1,即使他有成千上萬條操作,也只是個較大常數,這一類的時間複雜度為o(1);
(2)o(logn):對數階,如二分搜尋演算法。操作的數量與輸入資料的規模 n 的比例是 log2 (n)。n = 1,000,000 -> 30 operations
比如: 1,3,5,6,7,9;找出7
如果全部遍歷時間頻度為n;
二分查詢每次砍斷一半,即為n/2;
隨著查詢次數的提公升,頻度變化作表:
查詢次數 時間頻度
1 n/2
2 n/2^2
3 n/2^3
k n/2^k
當最後找到7的時候時間頻度則是1;
也就是:
n/2^k = 1;
n = 2^k;
k則是以2為底,n的對數,就是log2n;
那麼二分查詢的時間複雜度就是o(log2n);
(3)o(n):線性階,如n個數內找最大值。操作的數量與輸入資料的規模 n 成正比。n = 10,000 -> 5000 operations
這一類演算法中操作次數和n正比線性增長。
(4)o(nlogn):對數階,如快速排序演算法
上面看了二分查詢,是logn的(logn沒寫底數預設就是log2n);
線性對數階就是在logn的基礎上多了乙個線性階;
比如這麼乙個演算法流程:
陣列a和b,a的規模為n,遍歷的同時對b進行二分查詢,如下**:
for(int i =0;i(5)o(n^2):平方階,如選擇排序,氣泡排序。操作的數量與輸入資料的規模 n 的比例為二次平方。n = 500 -> 250,000 operations
long summn(int n, int m)
(6)o(n^3):立方階,如兩個n階矩陣的乘法運算。操作的數量與輸入資料的規模 n 的比例為三次方。n = 200 -> 8,000,000 operations
long summnk(int n, int m,int k)
(7)o(2^n):指數階,如n個元素集合的所有子集的演算法。指數級的操作,快速的增長。n = 20 -> 1048576 operations
(8)o(n!):階乘階,如n個元素全部排列的演算法
演算法時間複雜度計算
本部落格主要講解下演算法時間複雜度的基本計算過程。演算法時間複雜度是指演算法中基本操作的執行次數。記為t n o f n t n 為增長比最快項的係數。計算步驟 舉例說明 例1 void funfirst int n step1 基本操作是 j i 2 step2 確定規模,根據迴圈條件,確定規模為...
演算法時間複雜度的計算
定義 如果乙個問題的規模是n,解這一問題的某一演算法所需要的時間為t n 它是n的某一函式 t n 稱為這一演算法的 時間複雜性 求解演算法的時間複雜度的具體步驟是 1 找出演算法中的基本語句 演算法中執行次數最多的那條語句就是基本語句,通常是最內層迴圈的迴圈體。2 計算基本語句的執行次數的數量級 ...
演算法時間複雜度的計算
一 概念 時間複雜度 總運算次數表示式中受到n的影響最大的那一項 二 概念解釋 由於機器執行環境等的影響,的運算時間並不能準確的測算出來。但是,運算之間和演算法中語句的執行次數是成正比的,所以可以用語句之行次數來表徵時間複雜度的大小 三 計算方法 在計算演算法的時間複雜度的時候,先找出基本操作,再根...