在計算器科學中,樹(英語:tree)是一種抽象數據類型或是實現這種抽象數據類型的數據結構,用來模擬具有樹狀結構性質的數據集合。它是由n(n>0)個有限節點組成一個具有層次關系的集合。把它叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:
- 每個節點有零個或多個子節點;
- 沒有父節點的節點稱為根節點;
- 每一個非根節點有且只有一個父節點;
- 除了根節點外,每個子節點可以分為多個不相交的子樹;
1、二叉樹
二叉樹:每個節點最多含有兩個子樹的樹稱為二叉樹。(我們一般在書中試題中見到的樹是二叉樹)
在二叉樹的概念下又衍生出滿二叉樹和完全二叉樹的概念
滿二叉樹:除最后一層無任何子節點外,每一層上的所有結點都有兩個子結點。也可以這樣理解,除葉子結點外的所有結點均有兩個子結點。節點數達到最大值,所有葉子結點必須在同一層上。
完全二叉樹:若設二叉樹的深度為h,除第 h 層外,其它各層 (1~(h-1)層) 的結點數都達到最大個數,第h層所有的結點都連續集中在最左邊,這就是完全二叉樹。
算法實現
二叉樹:
private static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
二叉樹的遍歷方式
例:
圖1-1 一個二叉樹的例子
前序遍歷:根節點->遍歷左子樹->遍歷右子樹
圖1-1中的二叉樹的前序遍歷的順序為{10,6,4,8,14,12,17}
中序遍歷:遍歷左子樹->根節點->遍歷右子樹(可以理解為對根節點所在層的投影)
圖1-1中的二叉樹的中序遍歷的順序為{4,6,8,10,12,14,17}
后序遍歷:遍歷左子樹->遍歷右子樹->根節點
圖1-1中的二叉樹的中序遍歷的順序為{4,8,6,12,17,14,10}
這3種遍歷都有遞歸和循環兩種不同的實現方法,每種遍歷的遞歸實現都比循環實現要更簡潔很多。
2、二叉查找樹
二叉查找樹是二叉樹的衍生概念:
二叉查找樹(英語:Binary Search Tree),也稱為二叉搜索樹、有序二叉樹(ordered binary tree)或排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
- 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
- 若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
- 任意節點的左、右子樹也分別為二叉查找樹;
二叉查找樹相比於其他數據結構的優勢在於查找、插入的時間復雜度較低為 O ( log n ) 。二叉查找樹是基礎性數據結構,用於構建更為抽象的數據結構,如集合、多重集、關聯數組等。
3、 平衡二叉樹(AVL樹)
平衡二叉樹:當且僅當任何節點的兩棵子樹的高度差不大於1的二叉樹;
其中AVL樹是最先發明的自平衡二叉查找樹,是最原始典型的平衡二叉樹。
平衡二叉樹是基於二叉查找樹的改進。由於在某些極端的情況下(如在插入的序列是有序的時),二叉查找樹將退化成近似鏈或鏈,此時,其操作的時間復雜度將退化成線性的,即O(n)。所以我們通過自平衡操作(即旋轉)構建兩個子樹高度差不超過1的平衡二叉樹。
3、紅黑樹
紅黑樹也是一種自平衡的二叉查找樹。
通過對任何一條從根到葉子的路徑上各個節點着色的方式的限制,紅黑樹確保從根到葉子節點的最長路徑不會超過最短路徑的兩倍,用非嚴格的平衡來換取增刪節點時候旋轉次數的降低,任何不平衡都會在三次旋轉之內解決
紅黑樹多用於搜索,插入,刪除操作多的情況下
- 每個結點不是紅的就是黑的。
- 根結點是黑的。
- 每個葉結點都是黑的。
- 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
- 對於任意結點而言,其到葉結點樹尾端NIL指針的每條路徑都包含相同數目的黑結點。
4、B樹
B-樹就是B樹,-只是一個符號.
B樹(B-Tree)是一種自平衡的樹,它是一種多路搜索樹(並不是二叉的),能夠保證數據有序。同時它還保證了在查找、插入、刪除等操作時性能都能保持在O(logn),為大塊數據的讀寫操作做了優化,同時它也可以用來描述外部存儲(支持對保存在磁盤或者網絡上的符號表進行外部查找)
特點:
- 定義任意非葉子結點最多只有M個兒子;且M>2
- 根結點的兒子數為[2, M]
- 除根結點以外的非葉子結點的兒子數為[M/2, M]
- 每個結點存放至少M/2-1(取上整)和至多M-1個關鍵字;(至少2個關鍵字)
- 非葉子結點的關鍵字個數=指向兒子的指針個數-1
- 非葉子結點的關鍵字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]
- 非葉子結點的指針:P[1], P[2], …, P[M],其中P[1]指向關鍵字小於K[1]的子樹,P[M]指向關鍵字大於K[M-1]的子樹,其它P[i]指向關鍵字屬於(K[i-1], K[i])的子樹
- 所有葉子結點位於同一層
B+樹
B+樹是B-樹的變體,也是一種多路搜索樹
B+的搜索與B-樹也基本相同,區別是B+樹只有達到葉子結點才命中(B-樹可以在非葉子結點命中),其性能也等價於在關鍵字全集做一次二分查找;
B+的特性:
- 所有關鍵字都出現在葉子結點的鏈表中(稠密索引),且鏈表中的關鍵字恰好是有序的
- 不可能在非葉子結點命中
- 非葉子結點相當於是葉子結點的索引(稀疏索引),葉子結點相當於是存儲(關鍵字)數據的數據層
- 更適合文件索引系統
使用場景:
文件系統和數據庫系統中常用的B/B+ 樹,他通過對每個節點存儲個數的擴展,使得對連續的數據能夠進行較快的定位和訪問,能夠有效減少查找時間,提高存儲的空間局部性從而減少IO操作。
他廣泛用於文件系統及數據庫中,如:
Windows:HPFS 文件系統
Mac:HFS,HFS+ 文件系統
Linux:ResiserFS,XFS,Ext3FS,JFS 文件系統
數據庫:ORACLE,MYSQL,SQLSERVER 等中
對比
B樹:有序數組+平衡多叉樹 B+樹:有序數組鏈表+平衡多叉樹
B+ 樹的優點:
- 層級更低,IO 次數更少
- 每次都需要查詢到葉子節點,查詢性能穩定
- 葉子節點形成有序鏈表,范圍查詢方便