轉自【五月的倉頡】 http://www.cnblogs.com/xrq730/p/5122436.htmlhtml
數據結構算法
數據結構是計算機存儲、組織數據的方式,是指數據相互之間存在一種或多種特定關係的數據元素的集合。一般狀況下,精心選擇的數據結構能夠帶來更高的運行或者存儲效率(這就是爲何咱們要研究數據結構的緣由),數據結構每每同高效的檢索算法和索引技術相關。數組
常見的數據結構有數組、棧、隊列、鏈表、樹、散列等,這些數據結構將是本數據結構的分類中重點研究的對象。數據結構
算法分析異步
算法是爲求解一個問題須要遵循的、被清楚指定的簡單指令的集合。對於一個問題,一旦某種算法給定而且(以某種方式)被肯定是正確的,那麼重要的異步就是肯定該算法將須要多少注入時間或空間等資源量的問題。若是:數據結構和算法
一、一個問題的求解算法居然須要長達一年時間,那麼這種算法就很難有什麼用處函數
二、一個問題須要若干個GB的內存的算法,在當前大多數機器上也是沒法使用的測試
數學基礎spa
不管是數據結構仍是算法分析,都用到了大量的數學基礎,下面將這些數學的基礎簡單總結一下:code
一、指數
(1)XAXB = XA+B
(2)XA/XB = XA-B
(3)(XA)B = XABsi
(4)XN + XN = 2XN ≠ X2N
(5)2N + 2N = 2N + 1
二、對數
(1)XA = B當且僅當logxB = A
(2)logAB = logCB / logCA
(3)logAB = logA + logB,A>0且B>0
三、級數
(1)∑2i = 2N+1 - 1
(2)∑Ai = (AN+1 - 1) / (A - 1),若0<A<1,則有∑Ai ≤ 1 / (1 - A)
四、模運算
若是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 }
對這個程序片斷的分析是簡單的:
一、聲明不記入時間
二、第10行和都14行各佔一個時間單元
三、第12行每次執行佔用4個時間單元(兩次乘法、一次加法和一次賦值),而執行N次共佔用4N個時間單元
四、第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比較大,這個算法就動不了了)。