知道一個算法執行多快佔用多少空間很是有用,以此來選擇解決當前問題的算法。 大 O 符號讓你能粗略的估計算法的運行時間和他使用了多少內存。 一個最壞的例子算法的運行須要的時間是O( n2 ) ,而且使用O(n)的空間。那麼這個算法真的運行緩慢還須要不少額外的空間。 計算大O的算法一般是經過數據分析進行的。咱們跳過數學分析,這個n關聯的是須要處理數據的數量,例如打印1000個元素的數組的每一個元素則 n = 1000。git
這裏對數學忘了的童鞋咱們來複習下數學的對數和指數等方面的知識以便於咱們來理解這幾個函數公式表明的意思。github
對數百度百科解釋:若是a的x次方等於N(a>0,且a不等於1),那麼數x叫作以a爲底N的對數(logarithm),記做x=logaN。其中,a叫作對數的底數,N叫作真數。 舉個例子: 以2爲底8的對數就是3。套入上面的概念,2(a)的3(x)次方等於8(N),那麼數3叫作以2爲底8的對數,記做3 = log2 (8) 。因爲把8放到右上角很難打出來因此這裏省略爲3 = log2 (8)也記作 log(8)。 注意:在大 O 記法中 log (n)的底數有多是其餘常數 好比2,3。物理上經常使用e,數學計算中經常使用10,計算機相關經常使用2,所以計算機裏經常使用是2。算法
指數百度百科解釋:指數是冪運算aⁿ(a≠0)中的一個參數,a爲底數,n爲指數,指數位於底數的右上角,冪運算表示指數個底數相乘。當n是一個正整數,aⁿ表示n個a連乘。當n=0時,aⁿ=1。 咱們來理解下 :冪運算 8=2x2x2 2的三次方標識3個2連乘 。對數運算 3 = log 2 (8)。 他們之間什麼關係呢看圖: 數組
NSArray *testArray = @[@"2",@"5」]; NSString *testStr = testArray[1]; 複製代碼
固然以前咱們講的進棧出棧也是這個複雜度。 這個算法的運行次數f(n) = 1,根據推導大O階的方法,第一步是將1改成1,在保留最高階項是,它沒有最高階項,所以這個算法的時間複雜度爲O(1); 注意:無論這個常數是多少,3或12,都不能寫成O(3)、O(12),而都要寫成O(1)。bash
int j = 1;
while (j <= n)
{
j *= 2;
}
複製代碼
可能你們看這個有點模糊解釋下: 語句1的頻度是1, 設語句2的頻度是f(n),
則:2^f(n) <= n;f(n)<=log2n , 取最大值f(n)=log2n, T(n)=O(log2n ) ,我手寫了下看下圖: 函數
NSArray *testArray = @[@"2",@"5"];
for (NSInteger i = 0; i < testArray.count; i++)
{
NSLog(@"%@",testArray[i]);
}
複製代碼
這個算法的運行次數f(n) = n, 也就是O(n) 由於循環體中的代碼需要執行n次。性能
for (i = 0; i< n ; i ++)
{
int j = 1;
while (j <= n)
{
j *= 2;
}
}
複製代碼
解釋:和上面對數階多了一層循環 就是乘以n學習
for (int i = 0; i < n ; i++)
{
for (int j = i ; j < n; j++)
{
}
}
複製代碼
注意:上面的內層循環j = i ;而不是0 由於i = 0時,內層循環執行了n次,當i=1時,執行了n-1次……當i=n-1時,執行了1次,因此總的執行次數爲: n+(n-1)+(n-1)+...+1 = n(n+1)/2 = n2/2 + n/2 根據大O推導方法,保留最高階項,n2/2 ,而後去掉這個項相乘的常數,1/2 所以,這段代碼的時間複雜度爲O( n2 )ui
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
for(k=0;k<j;k++)
x=x+2;
}
}
複製代碼
解釋:當i=m, j=k的時候,內層循環的次數爲k當i=m時, j 能夠取 0,1,...,m-1 , 因此這裏最內循環共進行了0+1+...+m-1=(m-1)m/2次因此,i從0取到n, 則循環共進行了: 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6因此時間複雜度爲O ( n3 ).spa
一般你不須要推算,能夠大概估算下。若是一層循環是O (n) ,若是是兩層循環就是 O( n2 ) ,三層循環就是 O( n3 ) , 以此類推。這個大O也是估計,和這個n 有很大的關係。例如,最壞的狀況下(插入排序)算法的O( n2 ) , 在理論上, 比運行時間(歸併排序) 算法的 O(n log n)要差。但對於少許的數據,插入排序是更快。