轉自【五月的倉頡】 http://www.cnblogs.com/xrq730/p/5122436.html
數據結構
數據結構是計算機存儲、組織數據的方式,是指數據相互之間存在一種或多種特定關系的數據元素的集合。通常情況下,精心選擇的數據結構可以帶來更高的運行或者存儲效率(這就是為什么我們要研究數據結構的原因),數據結構往往同高效的檢索算法和索引技術相關。
常見的數據結構有數組、棧、隊列、鏈表、樹、散列等,這些數據結構將是本數據結構的分類中重點研究的對象。
算法分析
算法是為求解一個問題需要遵循的、被清楚指定的簡單指令的集合。對於一個問題,一旦某種算法給定並且(以某種方式)被確定是正確的,那么重要的異步就是確定該算法將需要多少注入時間或空間等資源量的問題。如果:
1、一個問題的求解算法竟然需要長達一年時間,那么這種算法就很難有什么用處
2、一個問題需要若干個GB的內存的算法,在當前大多數機器上也是無法使用的
數學基礎
無論是數據結構還是算法分析,都用到了大量的數學基礎,下面將這些數學的基礎簡單總結一下:
1、指數
(1)XAXB = XA+B
(2)XA/XB = XA-B
(3)(XA)B = XABsi
(4)XN + XN = 2XN ≠ X2N
(5)2N + 2N = 2N + 1
2、對數
(1)XA = B當且僅當logxB = A
(2)logAB = logCB / logCA
(3)logAB = logA + logB,A>0且B>0
3、級數
(1)∑2i = 2N+1 - 1
(2)∑Ai = (AN+1 - 1) / (A - 1),若0<A<1,則有∑Ai ≤ 1 / (1 - A)
4、模運算
如果N整除A、N整除B,那么就說A與B模N同余,記為A≡B(mod N)。直觀地看,這意味着無論是A還是B被N去除,所得余數都是相同的,於是假如有A≡B(mod N),則:
(1)A + C ≡ B + C(mod N)
(2)AD ≡ BD (mod N)
時間復雜度
在計算機科學中,算法的時間復雜度是一個函數,它定量描述了該算法的運行時間。這是一個關於代表算法輸入值的字符串的長度的函數,時間復雜度常用大O符號表述,不包括這個函數的低階項和首項系數,使用這種方式時,時間復雜度可被稱為是漸進的,他考察當輸入值大小趨近無窮時的情況。
那么首先先看一個簡單的例子,這里是計算Σi3的一個簡單程序片段:
1 public static void main(String[] args) 2 { 3 System.out.println(sum(5)); 4 } 5 6 public static int sum(int n) 7 { 8 int partialSum; 9 10 partialSum = 0; 11 for (int i = 0; i <= n; i++) 12 partialSum += i * i * i; 13 14 return partialSum; 15 }
對這個程序片段的分析是簡單的:
1、聲明不記入時間
2、第10行和都14行各占一個時間單元
3、第12行每次執行占用4個時間單元(兩次乘法、一次加法和一次賦值),而執行N次共占用4N個時間單元
4、第11行在初始化i,測試i≤n和對i的自增都隱含着開銷,所有這些總開銷是初始化1個時間單元,所有的測試為N+1個時間單元,所有自增為N個時間單元,共2N+2個時間單元
忽略調用方法和返回值的開銷,得到總量是6N+4個時間單元,按照最開始的定義不包括這個函數的低階項和首項系數,因此我們說該方法的時間復雜度是O(N)。繼而,我們順便得出若干個一般法則:
法則一----for循環
一個for循環的運行時間至多是該for循環內部那些語句(包括測試)的運行時間乘以迭代的次數,因此假如一個for循環迭代N次,那么其時間復雜度應該為O(N)
法則二----嵌套for循環
從里向外分析這些循環,在一組嵌套循環內部的一條語句總的運行時間為該語句的運行時間乘以該組所有的for循環的大小的乘積,因此假如有以下代碼:
1 public static int mutliSum(int n) 2 { 3 int k = 0; 4 for (int i = 0; i < n; i++) 5 { 6 for (int j = 0; j < n; j++) 7 { 8 k++; 9 } 10 } 11 12 return k; 13 }
則其時間復雜度應為O(N2)
法則三----順序語句
將各個語句的運行時間求和即可,比如有以下代碼:
1 public static int sum(int n) 2 { 3 int k = 0; 4 5 for (int i = 0; i < n; i++) 6 k++; 7 for (int i = 0; i < n; i++) 8 { 9 for (int j = 0; j < n; j++) 10 { 11 k++; 12 } 13 } 14 15 return k; 16 }
第一個for循環的時間復雜度為N,第二個嵌套for循環的時間復雜度為N2,綜合起來看sum方法的時間復雜度為O(N2)
常見的時間復雜度與時間效率的關系有如下的經驗規則:
O(1) < O(log2N) < O(n) < O(N * log2N) < O(N2) < O(N3) < 2n < 3n < n!
至於每種時間復雜度對應哪種數據結構和算法,后面都會講到,從上面的經驗規則來看:前四個算法效率比較高,中間兩個差強人意,后三個比較差(只要n比較大,這個算法就動不了了)。