數據結構與算法——C語言描述 個人筆記
樹和二叉樹
前言
在生活中,線結構是最基本並且也是最常用的,但是有許多邏輯關系並不是簡單的線性關系,在實際的場景中,往往存在一對多甚至是多對多的情況。
這時就需要非線性結構了,而樹結構則是一類重要的非線性結構,樹是以分支關系定義的層次結構,並且在現實生活中有廣泛的應用。
比如說人類社會的家譜:

滿 門 忠 烈
機構里的職級關系也可以用樹表示:

還有許多抽象的東西也可以表示成一棵樹,比如說操作系統中的文件目錄的組織結構、一本書的目錄:
這種結構類似於自然界中的樹一樣,從根里衍生出許多枝干,再從枝干中衍生出許多更小的枝干,最后衍生出更多的葉子。
樹的概念和定義
樹的定義
樹(Tree)是n(n>=0)個結點的有限集。
當n=0(即無結點)時,稱為空樹,空樹是樹的特例。
當n>0時為非空樹,對於非空樹:
-
必有且只有一個稱之為根(Root)的結點。
-
除根結點以外的n-1個結點可以划分為m個根的子樹(SubTree)。
樹其實也是一種遞歸的實現,即樹的定義之中還用到了樹的概念。
對比線性表和樹的結構,他們有很大的不同。
線性結構 | 樹結構 |
---|---|
第一個數據元素:無前驅 | 根結點:無雙親,唯一 |
最后一個數據元素:無后繼 | 葉結點:無孩子,可以多個 |
中間元素:一個前去一個后繼 | 中間節點:一個雙親多個孩子 |
樹的固有特性
-
非空樹至少有一個結點,只有一個結點的樹稱為最小樹,這個結點稱為樹的根結點或者簡稱為樹根。
-
在含有多個結點的樹中,除了根結點以外,其余的結點構成若干棵子樹(一棵樹是由若干個子樹構成的),各子樹間互不相交。
圖中的兩個結構就不符合定義,因為他們都有相交的子樹。
-
每顆子樹除了根結點以外,每個節點有且只有一個直接前驅,但可以有0到多個直接后繼。
樹的基本術語
-
結點:樹中的一個個獨立單元。包含一個數據元素和若干指向其他節點的分支信息。
-
結點的度(De-gree):一個結點的子樹個數。
-
樹的度:樹內各結點度的最大值。
因為這棵樹結點的度的最大值是結點D的度,為3,所以樹的度也為3。
-
葉結點(Leaf):度為0的節點,即無后繼的結點稱為葉結點或終端結點。
-
分支結點:度不為0的結點,又稱為非終端結點,除根結點外,非終端節點也稱為內部節點。
-
結點的層次(Level):從根結點開始定義,根結點的層次為1,根的直接后繼的層次為2,依此類推。
-
結點的層序編號:將樹中的結點按照從上到下,同層按照從左到右的次序排成一個線性序列,依次給他們編以從1開始的連續的自然數。
-
樹的高度/深度(Depth):樹中所有結點的層次的最大值,圖中的樹深度為4。
- 空樹的高度為0。
- 只有根結點的樹的高度為1。
-
森林(Forest):m(m>=0)棵互不相交的樹的集合。對樹中每個結點而言,其子樹的集合即為森林。將一棵非空非最小樹的樹根結點刪去,樹就變成一個森林。
-
孩子結點(Child):一個結點的直接后繼稱為該結點的孩子節點。
-
雙親結點(Parent):一個結點的直接前驅稱為該節點的雙親結點。
-
兄弟結點(Sibling):同一雙親結點的孩子之間互相稱為兄弟結點。
-
有序樹:將樹中結點的各子樹看成從左到右是有先后次序的(不能互換),則稱為有序樹,否則稱為無序樹。
二叉樹
二叉樹的定義
滿足以下兩個條件的樹形結構稱為二叉樹(Binary Tree):
-
每個結點最多有兩棵子樹(即不存在度大於2的結點)。
-
二叉樹的子樹有左右之分,其次序不能任意顛倒,即使樹中某結點只有一棵子樹,也要區分它是左子樹還是右子樹。
二叉樹結點的兩個孩子結點,左邊的被稱為左孩子(Left child),右邊的被稱為右孩子(Right child)。兩個孩子結點也有左右之分,次序不能任意顛倒。
二叉樹的五種基本形態:

前面有關樹的術語都適用於二叉樹。
二叉樹的性質
- 在二叉樹的第i層上(i從1開始計數)最多有2i-1個結點(i>=1)。
- 高度為k的二叉樹最多有2k-1個結點(k>=1)。
- 具有n(n>=1)個結點的完全二叉樹的高度最多為n,最少為(log2n)+1。
- 對任何一棵二叉樹,如果其葉結點有n個,度為2的結點有m個,則有:n=m+1。
- 如果對一棵有n個結點的完全二叉樹(其深度為(log2n)+1)的結點按層序編號(從第一層到(log2n)+1層,每層從左到右),對任一結點i(1<=i<=n)有:
- 如果i=1,則結點i是二叉樹的根,無雙親(屬實孤兒);如果i>1,則其雙親是結點i/2。
- 如果2i>n,則結點i無左孩子(結點i為葉子結點);否則其左孩子是結點2i。
- 如果2i+1>n,則結點i無右孩子;否則其右孩子是結點2i+1。
- n個結點可以組成1/(n+1)*[(2n)!/(n!*n!)]種不同構的二叉樹。
特殊二叉樹
-
滿二叉樹:在一棵二叉樹中,如果所有分支(非葉子結點)都存在左子樹和右子樹,並且所有的葉子都在同一層上(高度為k的二叉樹且有2k-1個結點)。
說白了就是每個分支都是滿的。
-
完全二叉樹:把一棵具有n個結點的二叉樹按層序編號,如果編號為i(1<=i<=n)的結點和同樣深度的滿二叉樹中編號i的節點在二叉樹中位置完全相同,那么這棵二叉樹被稱為完全二叉樹。也可以理解為把一棵滿二叉樹的最后一層結點,從左向右連續卻掉若干個結點,那么它就是完全二叉樹。
(可以看到這個二叉樹編號從1到12的12個結點和上圖的二叉樹的12個結點的位置完全對應,所以這個樹是完全二叉樹。)
滿二叉樹一定是完全二叉樹,但完全二叉樹不一定是滿二叉樹。
在完全二叉樹或滿二叉樹中,如果某個結點沒有左兒子,那么他一定沒有右兒子(即該結點是一個葉結點)。