淺談數據結構之樹,以後再也不怕面試官問了!

本篇只涉及樹的概念範圍和應考思路,不涉及具體結構或算法的實現與思考,具體的結構或算法會在後面跟新。

在計算器科學中,樹(英語:tree)是一種抽象數據類型或是實現這種抽象數據類型的數據結構,用來模擬具有樹狀結構性質的數據集合。它是由n(n>0)個有限節點組成一個具有層次關係的集合。把它叫做“樹”是因爲它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的

特點:

①每個節點有零個或多個子節點;
②沒有父節點的節點稱爲根節點;
③每一個非根節點有且只有一個父節點;
④除了根節點外,每個子節點可以分爲多個不相交的子樹;

淺談數據結構之樹,以後再也不怕面試官問了!
然後你要知道一大堆關於樹的術語:度,葉子節點,根節點,父節點,子節點,深度,高度。

二叉樹

二叉樹:每個節點最多含有兩個子樹的樹稱爲二叉樹。(我們一般在書中試題中見到的樹是二叉樹,但並不意味着所有的樹都是二叉樹。)

在二叉樹的概念下又衍生出滿二叉樹和完全二叉樹的概念

滿二叉樹:除最後一層無任何子節點外,每一層上的所有結點都有兩個子結點。也可以這樣理解,除葉子結點外的所有結點均有兩個子結點。節點數達到最大值,所有葉子結點必須在同一層上
完全二叉樹:若設二叉樹的深度爲h,除第 h 層外,其它各層 (1~(h-1)層) 的結點數都達到最大個數,第h層所有的結點都連續集中在最左邊,這就是完全二叉樹。

算法實現(見笑)

二叉樹:

 private static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
TreeNode(int x) { val = x; }
}

二叉樹的遍歷方式

先序遍歷:先根節點->遍歷左子樹->遍歷右子樹

中序遍歷:遍歷左子樹->根節點->遍歷右子樹

後序遍歷:遍歷左子樹->遍歷右子樹->根節點

淺談數據結構之樹,以後再也不怕面試官問了!
4

深度優先搜索(DFS)與廣度優先搜索(BFS)

實現:bfs=隊列,入隊列,出隊列 一次訪問一條路徑;dfs=棧,壓棧,出棧 一次訪問多條路徑(來自知乎)

關係:用DFS解決的問題都可以用BFS解決。DFS易於編寫(遞歸),時間消耗較少但是容易發生爆棧,而BFS可以控制隊列的長度。

2.動態查找樹

2.1 二叉查找樹

二叉查找樹是二叉樹的衍生概念:

二叉查找樹(英語:Binary Search Tree),也稱爲二叉搜索樹、有序二叉樹(ordered binary tree)或排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
1若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
2.若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
3.任意節點的左、右子樹也分別爲二叉查找樹;
4.沒有鍵值相等的節點。



二叉查找樹相比於其他數據結構的優勢在於查找、插入的時間複雜度較低爲 O ( log ⁡ n ) 。二叉查找樹是基礎性數據結構,用於構建更爲抽象的數據結構,如集合、多重集、關聯數組等。

2.2 平衡二叉樹(AVL樹)

平衡二叉樹:當且僅當任何節點的兩棵子樹的高度差不大於1的二叉樹;

其中AVL樹是最先發明的自平衡二叉查找樹,是最原始典型的平衡二叉樹。

平衡二叉樹是基於二叉查找樹的改進。由於在某些極端的情況下(如在插入的序列是有序的時),二叉查找樹將退化成近似鏈或鏈,此時,其操作的時間複雜度將退化成線性的,即O(n)。所以我們通過自平衡操作(即旋轉)構建兩個子樹高度差不超過1的平衡二叉樹。

具體可以參閱1962年G.M. Adelson-Velsky 和 E.M. Landis的論文"An algorithm for the organization of information"。(這個坑我會以後補)

2.3 紅黑樹

紅黑樹也是一種自平衡的二叉查找樹。
1.每個結點要麼是紅的要麼是黑的。(紅或黑)
2.根結點是黑的。 (根黑)
3.每個葉結點(葉結點即指樹尾端NIL指針或NULL結點)都是黑的。 (葉黑)
4.如果一個結點是紅的,那麼它的兩個兒子都是黑的。 (紅子黑)
5.對於任意結點而言,其到葉結點樹尾端NIL指針的每條路徑都包含相同數目的黑結點。(路徑下黑相同)




淺談數據結構之樹,以後再也不怕面試官問了!

如圖就是一棵典型的紅黑樹。保證紅黑樹滿足它的基本性質,就是在調整數據結構自平衡。

而紅黑樹自平衡的調整操作方式就有旋轉和變色兩種。

紅黑樹是一種應用很廣的數據結構,如在Java集合類中TreeSet和TreeMap的底層,C++STL中set與map,以及linux中虛擬內存的管理。

2.4 哈夫曼樹(Huffman Tree)

哈夫曼樹是一種帶權路徑長度最短的二叉樹,也稱爲最優二叉樹。

一般可以按下面步驟構建:

1,將所有左,右子樹都爲空的作爲根節點。
2,在森林中選出兩棵根節點的權值最小的樹作爲一棵新樹的左,右子樹,且置新樹的附加根節點的權值爲其左,右子樹上根節點的權值之和。注意,左子樹的權值應小於右子樹的權值。
3,從森林中刪除這兩棵樹,同時把新樹加入到森林中。
4,重複2,3步驟,直到森林中只有一棵樹爲止,此樹便是哈夫曼樹。


大家可能更多聽說的是哈夫曼編碼,其實就是哈夫曼樹的應用。即如何讓電文中出現較多的字符采用盡可能短的編碼且保證在譯碼時不出現歧義。
淺談數據結構之樹,以後再也不怕面試官問了!

3.多路查找樹

大規模數據存儲中,實現索引查詢這樣一個實際背景下,樹節點存儲的元素數量是有限的(如果元素數量非常多的話,查找就退化成節點內部的線性查找了),這樣導致二叉查找樹結構由於樹的深度過大而造成磁盤I/O讀寫過於頻繁,進而導致查詢效率低下。

3.1 B樹

B樹(英語:B-tree)是一種自平衡的樹,能夠保持數據有序。這種數據結構能夠讓查找數據、順序訪問、插入數據及刪除的動作,都在對數時間內完成。B樹,概括來說是一個一般化的二叉查找樹(binary search tree),可以擁有最多2個子節點。與自平衡二叉查找樹不同,B樹適用於讀寫相對大的數據塊的存儲系統,例如磁盤。
1.根結點至少有兩個子女。

2.每個中間節點都包含k-1個元素和k個孩子,其中 m/2 <= k <= m

3.每一個葉子節點都包含k-1個元素,其中 m/2 <= k <= m

4.所有的葉子結點都位於同一層。

5.每個節點中的元素從小到大排列,節點當中k-1個元素正好是k個孩子包含的元素的值域分劃。

淺談數據結構之樹,以後再也不怕面試官問了!
如圖所示就是一顆符合規範的B樹,由於相比於磁盤IO的速度,內存中的耗時幾乎可以省略,所以只要樹的高度足夠低,IO次數足夠小,就可以提升查詢性能。

B樹的增加刪除同樣遵循自平衡的性質,有旋轉和換位。

B樹的應用是文件系統及部分非關係型數據庫索引。

3.2 B+樹

B+ 樹是一種樹數據結構,通常用於關係型數據庫(如Mysql)和操作系統的文件系統中。B+ 樹的特點是能夠保持數據穩定有序,其插入與修改擁有較穩定的對數時間複雜度。B+ 樹元素自底向上插入,這與二叉樹恰好相反。

在B樹基礎上,爲葉子結點增加鏈表指針(B樹+葉子有序鏈表),所有關鍵字都在葉子結點 中出現,非葉子結點作爲葉子結點的索引;B+樹總是到葉子結點才命中。

b+樹的非葉子節點不保存數據,只保存子樹的臨界值(最大或者最小),所以同樣大小的節點,b+樹相對於b樹能夠有更多的分支,使得這棵樹更加矮胖,查詢時做的IO操作次數也更少。
淺談數據結構之樹,以後再也不怕面試官問了!
這通常在多數節點在次級存儲比如硬盤中的時候出現。通過最大化在每個內部節點內的子節點的數目減少樹的高度,平衡操作不經常發生,而且效率增加了。

3.3 B*樹

B*樹是B+樹的變體,在B+樹的非根和非葉子結點再增加指向兄弟的指針

在B+樹基礎上,爲非葉子結點也增加鏈表指針,將結點的最低利用率從1/2提高到2/3。

3.4 R樹

R樹是用來做空間數據存儲的樹狀數據結構。例如給地理位置,矩形和多邊形這類多維數據建立索引。

R樹的核心思想是聚合距離相近的節點並在樹結構的上一層將其表示爲這些節點的最小外接矩形(MBR),這個最小外接矩形就成爲上一層的一個節點。因爲所有節點都在它們的最小外接矩形中,所以跟某個矩形不相交的查詢就一定跟這個矩形中的所有節點都不相交。葉子節點上的每個矩形都代表一個對象,節點都是對象的聚合,並且越往上層聚合的對象就越多。也可以把每一層看做是對數據集的近似,葉子節點層是最細粒度的近似,與數據集相似度100%,越往上層越粗糙。

淺談數據結構之樹,以後再也不怕面試官問了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章