二叉樹與樹
阿新 • • 發佈:2020-08-06
樹形結構
- 一個結構不空,其中就存在這唯一的起始結點,稱為樹根(root)
- 按結構的連線關係,樹根外的其餘結點都有且只有 一個前驅,但另一方面,一個結點可以有 0個或者多個後繼,另外,在非空的樹結構中一定有寫結點並不連線到其他結點,這種結點與表的尾結點性質類似,但一個樹結構裡可以存在多個 這種結點
- 結構裡的所有結點都 在樹根結點通過後繼關係可達的結點集合裡,換句話說,從樹根結點出發,經過若干次後繼關係可以達到結構中的任意結點。
- 從這種結構 裡的任意兩個 不同結點出發,通過後繼關係可達的兩個結點的幾個,或者互不相交,或者一個集合是另一個集合的子集
二叉樹
- 二叉樹是一種最簡單的樹形結構,其特點是樹中每個結點之多 關聯到兩個後繼結點,也就是說,一個結點的關聯結點數可以 是0,1或2。另一個特點是一個結點關聯的後繼結點明確地分左右,或為其左關聯結點,或為其右關聯結點。
- 二叉樹定義:二叉樹是結點的有窮集合,這個集合或者是空集,或者其中有一個稱為根節點的特殊結點,其餘結點分數兩棵不相交 的 二叉樹,這兩顆二叉樹分別是原二叉樹(或者說是原二叉樹的根節點)的左子樹和右子樹
- 如圖所示,途中給出了幾種二叉樹,其中左邊一棵樹比較符合直觀,根結點有兩棵子樹,具有一層層 的結構;中間是一棵只包含根結點的二叉樹;右邊也是一棵二叉樹,但其每個結點都只有一棵右子樹
- 概念:
- 不包含任何結點的二叉樹稱為空樹
- 只包含一個結點的二叉樹是一棵單點樹
- 一般而言 ,一棵二叉樹可以包含任一個結點
- 一棵二叉樹的根節點稱為該樹的子樹根結點的父結點,與之對應,子樹的根節點稱為二叉樹樹根結點的子節點,父結點與子節點的概念是相對的
- 可認為從父結點到子結點有一條連線,稱為從父結點到子結點的邊,注意,這種邊有方向,形成一種單方向的父結點/子結點關係。基於父子關係可以定義其傳遞關係,稱為祖先/子孫關係,它決定一個結點的祖先結點,或子孫結點。父結點相同的兩個結點互為兄弟結點。
- 在二叉樹裡有些結點的兩棵子樹 都空,沒有子結點,這種結點稱為樹葉(結點)。書中其餘 結點 稱為分支結點
- 一個結點的子結點個數稱為該結點的度數,顯然,二叉樹中樹葉結點的度數為0,分支結點的度數是 1或者2
- 路徑:從一個祖先結點到其任何子孫結點都存在一系列邊,形成從前者到後者的聯絡,這樣一些列首尾相連的邊稱為樹中的一條路徑,路徑中邊的條數稱為該路徑的長度,顯然,從一個結點到其子結點有一條長度為1的路徑,每個結點到其自身有一條長度為0的路徑
- 層:二叉樹是一種層次結構,將其樹根看作最高層元素,如果有子結點,其子結點看作下一層元素,規定二叉樹樹根層數為0,對位於k層的結點,其子結點是k+1層元素,如此下去,二叉樹的所有結點可以按這種關係分為一層層元素,易見,從樹根到任一結點的路徑長度就是該結點所在 的層數,也稱為該節點的層數
- 高度:一棵二叉樹的高度(也稱為深度)是樹中結點的最大層數,也就是這棵樹裡最長路徑的長度,樹的高度是二叉樹的整體性質,只有根節點的樹高度為0
滿二叉樹:如果二叉樹 中所有 分支結點的度數都是2,則稱它為一棵滿二叉樹。滿二叉樹是一般二叉樹的一個子集,如圖所示:
擴充二叉樹:對二叉樹T,加入足夠多的新葉結點,使T的原有結點都邊稱度數為2的分支結點,得到的二叉樹稱為T的擴充二叉樹,擴充二叉樹中新增的結點稱為外部結點,原樹T的結點稱為內部結點,空樹的擴充套件二叉樹規定為空樹。如下圖所示:
完全二叉樹:對於 一棵高度為 h的二叉樹,如果其第0層至第h-1層的結點都滿 ,也就是說,對所有0<=i<=h-1,第i層都有兩個結點,如果下一層的結點不滿,則所有結點在最左邊連續排列,空位都在最右邊,這樣的二叉樹就是一個完全二叉樹。如圖
下面是一個基本的二叉樹抽象資料型別的定義
ADT BinTree: # 一個二叉樹抽象資料型別 BinTree(self,data, left, right) # 構造操作,建立一個新的二叉樹 is_empty(self) # 判斷self是否為一個空二叉樹 num_nodes(self) # 求二叉樹的結點個數 data(self) # 獲取二叉樹根儲存的資料 left(self) # 獲取二叉樹的左子樹 right(self) # 獲取 二叉樹的右子樹 set_left(self, btree) # 用btree取代原來的左子樹 set_right(self, btree) # 用btree取代原來的右子樹 traversal(self) # 遍歷二叉樹中各結點資料的迭代器 forall(self, op) # 對二叉樹中的每個結點的資料執行操作op
二叉樹的基本操作包括建立二叉樹,判斷是否是空樹,子樹操作,結點遍歷
遍歷二叉樹
- 每棵二叉樹右唯一的根結點,可以將其看作這棵二叉樹的唯一標識,是基於樹結構的處理過程的入口。二叉樹中每個結點可能儲存一些資料,因此也是彙集型的資料結構。
- 遍歷一棵二叉樹,就是按照某種系統化的方式範文二叉樹裡的每個結點一次,這一過程可以基於二叉樹的基本操作實現,遍歷中可能操作結點裡的資料
- 二叉樹的結構比較複雜,因此係統化遍歷右多種可能的方式,下面討論集中不同的演算法:
- 深度優先遍歷:順著一條路經儘可能向前探索,必要時回溯,對於二叉樹,最基本的回溯情況就是檢查完一個葉結點,由於無路可走,只能回頭
- 按深度優先方式遍歷一棵二叉樹,需要做三件事:
- 遍歷左子樹
- 遍歷右子樹
- 訪問根結點
- 下面用L、R、D表示這三項工作,如圖所示,選擇這三項工作的不同執行順序,就可以得到三種常見的遍歷順序,
- 先根序遍歷---按DLR順序
- 中根序遍歷---按LDR順序
- 後根序遍歷---按LRD順序
- 在遍歷過程中遇到子樹為空的情況,就立即結束處理並轉去繼續做下一步工作,例如,在先根序中遇到左子樹為空,就轉去遍歷相應的右子樹。
- 例子,按不同的深度優先方式遍歷下圖二叉樹
- 按先根序遍歷,先訪問根節點,而後以同樣方式順序遍歷左子樹和右子樹,得到的結點訪問序列:ABDHEICFJKG
- 按後根序遍歷,先以同樣方式遍歷左右子樹,最後訪問根節點,得到順序:HDIEBJKFGCA
- 按中根序遍歷,先以同樣方式遍歷左子樹,而後 訪問根節點,最後再以同樣方式遍歷右子樹,得到的遍歷序列:DHEIBAJFKCG
- 按深度優先方式遍歷一棵二叉樹,需要做三件事:
- 寬度優先遍歷:按路徑長度由近到遠的訪問結點,常見在每一層裡都 從左到右逐個訪問,上圖寬度優先遍歷結果為:ABCDEFGHIJK