開頭說點題外話,在帥張星球上看到一個提問(下圖),覺得帥張回答的很中肯很在理。論一個男生上進心的重要性,不上進找不到女朋友啊,當然了不要以為上進了就能找到女朋友!管他什么女朋友,我的心里只有學習!繼續我們的數據結構學習之旅,這一次我們學習的是樹。
樹的定義
樹(Tree)是n(n>=0)個結點的有限集。n=0時稱為空樹。
在任意一顆非空樹中:
(1)有且僅有一個特定的稱為根(Root)的結點。
(2)當n>1時,其余結點可分為m(m>0)個互不相交的有限集T1、T2、.....、Tm,其中每一個集合本身又是一棵樹,並且稱為根的子樹(SubTree)。
下圖就符合樹的定義:
其中根結點A有兩個子樹:
需要注意的是雖然子樹的個數沒有限制,但是它們一定是互不交互的。下面的圖明顯不符合互不交互的原則,所以不是樹。
樹的結點
樹的結點包含一個數據元素及若干指向其子樹的分支。結點擁有的子樹數稱為結點的度(Degree)。樹的度是樹內各結點度的最大值。
結點的層次從根開始定義起,根為第一層,根的孩子為第二層,以此類推。樹的深度(Depth)或高度是樹中結點的最大層次。
樹的存儲結構
二叉樹
二叉樹的定義
二叉樹(Binary Tree)是n(n>=0)個結點的有限集合,該集合或者為空集(空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱為根結點的左子樹和右子樹的二叉樹組成(子樹也為二叉樹)。
二叉樹的特點
- 每個結點最多有兩棵子樹,所以二叉樹中不存在度大於2的結點。
- 左子樹和右子樹是有順序的,次序不能任意顛倒。
- 即使樹中某結點只有一棵子樹,也要區分它是左子樹還是右子樹。
二叉樹五種基本形態
- 空二叉樹
- 只有一個根結點
- 根結點只有左子樹
- 根結點只有右子樹
- 根結點既有左子樹又有右子樹
幾種特殊的二叉樹
斜樹
左斜樹:右斜樹:
滿二叉樹
滿二叉樹:
完全二叉樹
完全二叉樹:
二叉樹的性質
二叉樹性質1
性質1:在二叉樹的第i層上至多有2i-1個結點(i>=1)
二叉樹性質2
性質2:深度為k的二叉樹至多有2k-1個結點(k>=1)
二叉樹性質3
性質3:對任何一棵二叉樹T,如果其終端結點數為n0,度為2的結點數為n2,則n0 = n2+1。
一棵二叉樹,除了終端結點(葉子結點),就是度為1或2的結點。假設n1度為1的結點數,則數T 的結點總數n=n0+n1+n2。我們再換個角度,看一下樹T的連接線數,由於根結點只有分支出去,沒有分支進入,所以連接線數為結點總數減去1。也就是n-1=n1+2n2,可推導出n0+n1+n2-1 = n1+2n2,繼續推導可得n0 = n2+1。
二叉樹性質4
性質4:具有n個結點的完全二叉樹的深度為[log2n ] + 1([X]表示不大於X的最大整數)。
由性質2可知,滿二叉樹的結點個數為2k-1,可以推導出滿二叉樹的深度為k=log2(n + 1)。對於完全二叉樹,它的葉子結點只會出現在最下面的兩層,所以它的結點數一定少於等於同樣深度的滿二叉樹的結點數2k-1,但是一定多於2k-1 -1。因為n是整數,所以2k-1 <= n < 2k,不等式兩邊取對數得到:k-1 <= log2n <k。因為k作為深度也是整數,因此 k= [log2n ]+ 1。
二叉樹性質5
性質5:如果對一顆有n個結點的完全二叉樹(其深度為[log2n ] + 1)的結點按層序編號(從第1層到第[log2n ] + 1層,每層從左到右),對任一結點i(1<=i<=n)有:
如果i=1,則結點i是二叉樹的根,無雙親;如果i>1,則其雙親是結點[i/2]。
如果2i>n,則結點i無左孩子(結點i為葉子結點);否則其左孩子是結點i。
如果2i+1>n,則結點i無右孩子;否則其右孩子是結點2i+1。
結合下圖很好理解:
二叉樹的存儲結構
二叉樹順序存儲結構
^代表不存在的結點。
對於右斜樹,順序存儲結構浪費存儲空間:
二叉樹的順序存儲結構缺點很明顯:不能反應邏輯關系;對於特殊的二叉樹(左斜樹、右斜樹),浪費存儲空間。所以二叉樹順序存儲結構一般只用於完全二叉樹。
二叉鏈表
鏈表每個結點包含一個數據域和兩個指針域:
其中data是數據域,lchild和rchild都是指針域,分別指向左孩子和右孩子。
二叉樹的二叉鏈表結點結構定義:
/*二叉樹的二叉鏈表結點結構定義*/
typedef struct BiNode
{
char data; /*結點數據*/
struct BiNode *lchild, *rchild; /*左右孩子指針*/
}BiNode,*BiTree;
參考:《大話數據結構》