【圖解數據結構】 樹


開頭說點題外話,在帥張星球上看到一個提問(下圖),覺得帥張回答的很中肯很在理。論一個男生上進心的重要性,不上進找不到女朋友啊,當然了不要以為上進了就能找到女朋友!管他什么女朋友,我的心里只有學習!繼續我們的數據結構學習之旅,這一次我們學習的是樹。

mark

樹的定義

樹(Tree)是n(n>=0)個結點的有限集。n=0時稱為空樹。

在任意一顆非空樹中:

(1)有且僅有一個特定的稱為根(Root)的結點。

(2)當n>1時,其余結點可分為m(m>0)個互不相交的有限集T1、T2、.....、Tm,其中每一個集合本身又是一棵樹,並且稱為根的子樹(SubTree)。

下圖就符合樹的定義:

mark

其中根結點A有兩個子樹:

markmark

需要注意的是雖然子樹的個數沒有限制,但是它們一定是互不交互的。下面的圖明顯不符合互不交互的原則,所以不是樹。

markmark

樹的結點

樹的結點包含一個數據元素及若干指向其子樹的分支。結點擁有的子樹數稱為結點的度(Degree)樹的度是樹內各結點度的最大值。

mark

mark

結點的層次從根開始定義起,根為第一層,根的孩子為第二層,以此類推。樹的深度(Depth)或高度是樹中結點的最大層次。

mark

樹的存儲結構

mark

二叉樹

二叉樹的定義

二叉樹(Binary Tree)是n(n>=0)個結點的有限集合,該集合或者為空集(空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱為根結點的左子樹和右子樹的二叉樹組成(子樹也為二叉樹)。

二叉樹的特點

  • 每個結點最多有兩棵子樹,所以二叉樹中不存在度大於2的結點
  • 左子樹和右子樹是有順序的,次序不能任意顛倒。
  • 即使樹中某結點只有一棵子樹,也要區分它是左子樹還是右子樹。

二叉樹五種基本形態

  1. 空二叉樹
  2. 只有一個根結點
  3. 根結點只有左子樹
  4. 根結點只有右子樹
  5. 根結點既有左子樹又有右子樹

幾種特殊的二叉樹

斜樹

mark

左斜樹:mark右斜樹:mark

滿二叉樹

mark

滿二叉樹:mark

完全二叉樹

mark

完全二叉樹:mark

二叉樹的性質

二叉樹性質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)有:

  1. 如果i=1,則結點i是二叉樹的根,無雙親;如果i>1,則其雙親是結點[i/2]。

  2. 如果2i>n,則結點i無左孩子(結點i為葉子結點);否則其左孩子是結點i。

  3. 如果2i+1>n,則結點i無右孩子;否則其右孩子是結點2i+1。

結合下圖很好理解:

mark

二叉樹的存儲結構

二叉樹順序存儲結構

mark

^代表不存在的結點。

對於右斜樹,順序存儲結構浪費存儲空間:

mark

二叉樹的順序存儲結構缺點很明顯:不能反應邏輯關系;對於特殊的二叉樹(左斜樹、右斜樹),浪費存儲空間。所以二叉樹順序存儲結構一般只用於完全二叉樹。

二叉鏈表

鏈表每個結點包含一個數據域和兩個指針域:

mark

其中data是數據域,lchild和rchild都是指針域,分別指向左孩子和右孩子。

mark

二叉樹的二叉鏈表結點結構定義:

/*二叉樹的二叉鏈表結點結構定義*/
typedef struct BiNode
{
	char data;		/*結點數據*/
	struct BiNode *lchild, *rchild;		/*左右孩子指針*/
}BiNode,*BiTree;

參考:《大話數據結構》

聲明:本文為博主學習感悟總結,水平有限,如果不當,歡迎指正。如果您認為還不錯,不妨點擊一下下方的 推薦按鈕,謝謝支持。轉載與引用請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM