線性關係(線性結構):是指在數據元素的非空有限集合中有且僅有一個首元素的數據元素,有且只有一個尾元素的數據元素,其他的數據元素均有且只有一個直接前驅元素和一個直接後繼元素
常見的線性結構:線性表,隊列,棧,串,數組。html
非線性結構:線性結構的元素之間具備線性關係,非線性結構中的元素之間再也不是序列的關係,他們呈現的是更復雜的層次關係,即一個數據元素有且僅有一個直接前驅,但可有另個或者多個直接後繼,顯然比序列關係複雜
常見非線性結構:樹,圖算法
PHP中的hashtable就是哈希表就是由數組和鏈表組成,一個長度爲16的數組中,每一個元素存儲的是一個鏈表的頭結點。而HashMap和Hashtable就是哈希表結構數據庫
操做PrintList,Find,Delete,Insert
1.使用數組(array)實現
定義一個數組的時候,一般須要對錶的大小進行估計(由於數組的元素之間物理地址是相連續的,因此須要一次性分配),通常須要估計的大一些,天然會浪費掉一些空間。
PrintList和Find確定是跟表的大小是相關的,也就是線性的。FindKth的花費就是常數時間
Insert和Delete的代價很大。好比在表的位置0插入(Insert)一個新元素,那麼整個數組的元素都要後移一位。刪除第一個元素也須要將後面的全部元素都向前移動一位。
因此表的結構使用數組來實現顯然不是好的選擇
2.使用鏈表(linked list)實現
鏈表是由一系列沒必要在內存中中相連的結構組成,每一個結構都含有表元素和一個執行包含該元素的後繼元素物理地址的結構的指針,稱之爲next指針。最後一個單元的next指針爲NULL
PrintList(L)和Find(L,Key),咱們只要將一個指針傳遞到該表的第一個元素,而後用一些next指針貫穿該表便可,花費時間是跟表的大小線性相關的。
FindKth(L,i)花費時間O(i)
Delete操做只是將被刪除元素的前驅元素的next指針修改成被刪除元素的next指針就能夠了
數組
Insert元素只須要一次malloc從系統申請一個新單元而且執行兩次指針調整就能夠了
數據結構
對於大量的輸入數據,鏈表的線性訪問時間太慢。樹的大部分操做的運行時間平均爲O(logN)。一棵樹是由N個節點和N-1條邊的集合,其中一個節點是根結點,每條邊都將某個節點鏈接到它的父親,而除去根結點外每個節點都有一個父親
樹的存儲實現:
結點即爲數據元素,存儲比較簡單和直接
分支描述的是關係,關係的存儲是複雜而多樣的,所以須要從存儲分支信息的角度入手分析可能的解決方案。編碼
1.雙親數組表示法
由於一條分支描述的是相鄰兩個結點(孩子和雙親的關係),因此就能在內存中存儲全部結點信息和全部的雙親關係spa
2.孩子鏈表表示法
存儲全部結點的信息和全部孩子的關係。
1>頭節點結構
3d
data域是數據域,用來存儲結點信息;
first域爲指針域,用來存儲結點孩子鏈表的入口地址,此鏈表記錄告終點的全部孩子信息
2>表節點結構
指針
childno域用來存儲某個孩子結點的編號
next域爲指針域,用來執行結點的下一個孩子所對應的表結點htm
3.左孩子右兄弟表示法
將結點最左邊的孩子(若是存在的話)成爲結點的左孩子,將位於結點右邊且緊挨着它的兄弟(若存在的話)稱爲該結點的右兄弟
二叉樹
遞歸樹的方式
先序遍歷:根左右
中序遍歷:左根右
後序遍歷:左右根
前序遍歷中第一個數字老是根節點
線索二叉樹
對一個二叉樹線索化以後,能夠獲得某種遍歷序列節點的前綴節點和後繼節點。線索二叉樹將一個二叉樹變成了雙向鏈表
哈夫曼樹
在計算機數據處理中,霍夫曼編碼使用變長編碼表對源符號(如文件中的一個字母)進行編碼,其中變長編碼表是經過一種評估來源符號出現機率的方法獲得的,出現機率高的字母使用較短的編碼,反之出現機率低的則使用較長的編碼,這便使編碼以後的字符串的平均長度、指望值下降,從而達到無損壓縮數據的目的
B-Tree
來源維基百科:
Rudolf Bayer 和 Ed McCreight 於1972年,在Boeing Research Labs 工做時發明了B 樹,可是他們沒有解釋B 表明什麼意義(若是有的話)。Douglas Comer 解釋說: 兩位做者歷來都沒解釋過B樹的原始意義。正如咱們所見,「balanced」, 「broad」 或 「bushy」 可能適合。其餘人建議字母「B」表明 Boeing。源自於他的贊助,不過,看起來把B樹看成「Bayer」樹更合適些
階爲M的B-樹的特色(來自數據結構與算法分析-C語言描述):
--|樹的根或者是樹葉節點,或者其兒子數在2和M之間
--|除根外,全部非樹葉節點的兒子數在M/2和M之間
--|全部樹葉都在相同深度上
全部數據都存放在樹葉節點上,當插入一個關鍵字,只有在訪問路徑上的那些內部節點纔有可能發生變化。
對於一個M階的樹,比較困難狀況發生在接收該關鍵字的節點已經有了M個關鍵字的時候,這個關鍵字是的該節點具備M+1個關鍵字,咱們能夠把它分裂成兩個節點。
他們分別具備「(M+1)/2向下和(M+1)/2」向上個關鍵字。因爲這個父節點多了一個兒子,咱們必須檢查這個節點是否被父節點接收,若是父節點已經有M個兒子,那麼這個父節點就要被分裂成兩個節點。咱們重複這個過程
直到找到一個父節點具備少於M個兒子,若是咱們分裂根節點,那麼咱們就要建立一個新的根,這個根有兩個兒子。
參考資料:
線索二叉樹:http://www.cnblogs.com/GumpYa...
哈夫曼編碼:https://zh.wikipedia.org/zh/%...
數據庫索引數據結構:http://www.cnblogs.com/zcy_so...