樹的概念本身是比較簡單的,絕大部分情況下,我們都不會討論樹這個大類,而是具體的某種類型的樹,比如各種類型的二叉樹。在具體的樹的類型中,各種不同的應用會根據他們的場景特點選擇特定類型的樹來處理元素的操作。比如,紅黑樹,平衡二叉樹,AVL平衡二叉樹,二叉堆......在此之前,我們需要對一些重要的概念進行比較,重點是比較他們的區別,否則說起某個具體的類型,腦海中可能完全是模糊的。
【樹】
樹的定義:
(1)每個元素稱為節點(node)。
(2)有一個特定的節點被稱為根節點或樹根(root)。
(3)除根節點之外的其余數據元素被分為個互不相交的集合,其中每一個集合本身也是一棵樹,被稱作原樹的子樹(subtree)。
對於節點,根,子樹的概念都不陌生。這里重要的概念在於除根節點外,也是互不相交的樹,這種分形的定義有點類似遞歸的概念,直接將樹與環區分開來。
樹的屬性:
對於樹,無論是什么類型的樹,有幾個重要的屬性概念,在各種樹的討論中,會被頻繁提及,這里進行集中說明:
節點/結點,根節點,父節點,子節點,兄弟節點 -- 這些都很容易理解,不在此說明
葉子節點:度為0,其實就是沒有子節點的節點,這里我之前會被"葉"的概念迷惑,但這里就只認他們為普通節點就好,只是沒有子節點,不要把它們想得太特殊,這個葉子節點,只是為了區分其它有子節點的節點而進行的區分手段;
節點的度:定義是子節點的個數,這里注意子節點就是嚴格的只與本節點直接相連的子節點,不要把子節點的下級也算在其中
節點的層次:根在第一層,根的子節點是第二層,后續的類推......
樹的深度:樹的最大層次
這幾個概念需要特別清楚,否則說起來各種類型的樹有什么特點,提到度、層次、深度等概念時可能還不清楚,那就無法准確理解后續的表述了。
【二叉樹】
這里進入一個比較重要的樹的類型了。后續的堆、紅黑樹、平衡樹...都是基於二叉樹的概念。
首先,二叉樹是一種樹。與樹不同的是,二叉樹的每個節點,最多有2個子節點(即二叉樹中不存在度大於2的節點)。二叉樹的子樹是有順序的,分為左子樹和右子樹(之所以要這么區分,是因為后續的場景會在此基礎上定義更多細節,從而形成有特殊作用的數據結構),即使只有一顆子樹,也是要區分左右的。
總結,最多2個子節點,且除了根節點,每個節點都分為左和右。當節點數n=0時,稱為空樹。
到了這里,我們可以看看一些常見的二叉樹種類:
- 滿二叉樹
- 完全二叉樹
- 完美二叉樹
- 二叉查找樹
- 平衡二叉樹
- 紅黑樹
- 堆(二叉堆)
【滿二叉樹】
國內對於滿二叉樹的定義是,每一層的節點數都達到了最大值,即:1,2,4,...。這樣一來,滿二叉樹的相關屬性就是確定的了,節點數為(2^k-1),其中k為層數。第i層上的結點個數為2^(i-1)。
國內滿二叉樹:
國外對於滿二叉樹的定義是,要么是葉子節點,要么度為2的節點。這里沒有要求每一層達到最大值。而國外對於完美二叉樹的定義是跟國內滿二叉樹的定義一致。
國外滿二叉樹:
【完全二叉樹】
其實前面的滿二叉樹,也是給后續的場景做鋪墊。到這里,很多相關的實用的場景就會高頻提及這些概念。完全二叉樹是一些重要結構的基礎。
1.除去最后一層節點,為完美二叉樹。
2.最后一層節點,依次從左往右排列。
根據這個定義,可以看看下圖中的二叉樹,它們都是完全二叉樹:
而對於下圖中示例,就不是完全二叉樹:
由於完全二叉樹的特點,我們可以使用數組進行節點數據的存儲,這一特點在一些排序的操作中很常用。