在電腦科學中，二元樹是每個節點最多隻有兩個分支（即不存在分支度大於 2 的節點）的樹結構。通常分支被稱作 左子樹 或 右子樹。二元樹的分支具有左右次序，不能隨意顛倒。 二元樹的第 i 層至多擁有 2i1 個節點；深度為 k 的二元樹至多總共有 2begin align k1 end align1 個節點（定義根節點所在深度 k_00），而總計擁有節點數符合的，稱為「滿二元樹」；深度為 k 有 n 個節點的二元樹，當且僅當其中的每一節點，都可以和深度 k 的滿二元樹，序號 1 到 n 的節點一對一對應時，稱為完全二元樹。對任何一棵非空的二元樹 T，如果其葉片（終端節點）數為 n_0，分支度為 2 的節點數為 n_2，則 n_0 n_2 1。 與普通樹不同，普通樹的節點個數至少為 1，而二元樹的節點個數可以為 0；普通樹節點的最大分支度沒有限制，而二元樹節點的最大分支度為 2；普通樹的節點無左、右次序之分，而二元樹的節點有左、右次序之分。 二元樹通常作為資料結構應用，典型用法是對節點定義一個標記函式，將一些值與每個節點相關聯。這樣標記的二元樹就可以實現二元搜尋樹和二元堆積，並應用於高效率的搜尋和排序。 圖論中的定義 二元樹是一個連通的無環圖，並且每一個頂點的度不大於 3。有根二元樹還要滿足根節點的度不大於 2。有了根節點之後，每個頂點定義了唯一的父節點，和最多 2 個子節點。然而，沒有足夠的資訊來區分左節點和右節點。如果不考慮連通性，允許圖中有多個連通分量，這樣的結構叫做森林。 性質 二元樹是一個有根樹，並且每個節點最多有 2 個子節點。非空的二叉樹，若樹葉總數為 n0，分支度為 2 的總數為 n2，則 n0 n2 1。 特殊型別 完全二元樹 完美二元樹 總節點 k 2h1 k 2h1 k 2h1 樹高 h h log_2k1 h log_2 k1 滿二元樹 在一顆二元樹中，除了葉節點外，每個節點都有 2 個子節點。 完美二叉樹 一棵深度為 k，且有 2begin align k end align1 個節點的二元樹，稱為完美二元樹（Perfect Binary Tree）。這種樹的特點是其中所有內部節點都有兩個子節點，並且所有葉子都處於同一級別。 性質 對於一棵深度為 k 的完美二叉樹： 共有 2k1 個結點 結點個數一定為奇數 第 i 層有 2i1 個結點 有 2k1 個葉子 完全二叉樹 在一顆二元樹中，若除最後一層外的其餘層都是滿的，並且最後一層要麼是滿的，要麼在右邊缺少連續若干節點，則此二元樹為完全二元樹（Complete Binary Tree）。具有 n 個節點的完全二元樹的深度為 log_2n1。深度為 k 的完全二元樹，至少有 2begin align k1 end align 個節點，至多有 2begin align k end align1 個節點。 儲存 在程式設計語言中能用多種方法來構造二元樹。 順序儲存表示 二元樹可以用陣列或連結串列來儲存，若是滿二元樹就能緊湊排列而不浪費空間。如果某個節點的索引為 i，（假設根節點的索引為 0）則在它左子節點的索引會是 2i 1，以及右子節點會是 2i 2；而它的父節點（如果有）索引則為 left lfloor frac i12 right rfloor。這種方法更有利於緊湊儲存和更好的訪問的區域性性，特別是在前序遍歷中。然而，它需要連續的儲存空間，這樣在儲存高度為 h 的 n 個節點所組成的一般樹時，將浪費很多空間。在最糟糕的情況下，如果深度為 h 的二元樹其每個節點都只有右孩子，則該儲存結構需要佔用 2h1 的空間，實際上卻有 h 個節點，浪費了不少空間，是順序儲存結構的一大缺點。 儲存結構 二叉樹的順序儲存表示 define MAX_TREE_SIZE 100 二叉樹的最大節點數 typedef TElemType SqBiTree MAX_TREE_SIZE 0 號單元儲存根節點 typedef struct int levelorder 即節點的層 按 滿二叉樹 計算 position 基本操作 二元樹 的順序儲存的基本操作 23 個 define ClearBiTree InitBiTree 在順序儲存結構中，兩函式完全一樣 define DestroyBiTree InitBiTree 在順序儲存結構中，兩函式完全一樣 void InitBiTree SqBiTree T －－－（SqBiTree T） 構造 空二元樹 T。因為 T 是陣列名稱，故不需要 int i for i0iMAX_TREE_SIZEi T iNil 初值為空 Nil 在主程中定義 void CreateBiTree SqBiTree T 按層序次序輸入二叉樹中結點的值 字元型或整型 構造順序儲存的二叉樹 T int i0 if CHAR 結點型別為字元 int l char s MAX_TREE_SIZE InitBiTree T 構造 空二元樹 T printf 請按層序輸入結點的值 字元，空格表示空結點，節點數 dnMAX_TREE_SIZE gets s 輸入字串 lstrlen s 求字串的長度 for ili 將字串賦值給 T T is i else 節點型別為整型 InitBiTree T 構造 空二元樹 T printf 請按層序輸入節點的值 整型，0 表示空節點，輸 999 結束。節點數 dnMAX_TREE_SIZE while 1 scanf dT i if T i999 T iNil break i endif for i1iMAX_TREE_SIZEi if T i121NilT iNil 此非根節點 不空 無雙親 printf 出現無雙親的非根節點formnT i exit ERROR int BiTreeDepth SqBiTree T 初始條件：二元樹 T 存在。操作結果：返回 T 的深度 int ij1 for iMAX_TREE_SIZE1i0i 找到最後一個節點 if T iNil break i 為了便於計算 do j while ipow 2j pow 是原型為 double pow double x double y 計算 x 的 y 次方，h log2k 1 來計算 二元樹 的深度 return j Status Root SqBiTree TTElemType e 初始條件：二元樹 T 存在。操作結果：當 T 不空，用 e 返回 T 的根，返回 OK；否則返回 ERROR，e 無定義 if BiTreeEmpty T T 空 return ERROR else eT 0 return OK TElemType Value SqBiTree Tposition e 初始條件：二元樹 T 存在，e 是 T 中某個結點 的位置 操作結果：返回處於位置 e 層，本層序號 的結點的值 return T int pow 2elevel1eorder2 Status Assign SqBiTree Tposition eTElemType value 初始條件：二叉樹 T 存在，e 是 T 中某個結點 的位置 操作結果：給處於位置 e 層，本層序號 的結點賦新值 value int iint pow 2elevel1eorder2 將層、本層序號轉為矩陣的序號 if valueNilT i121Nil 給葉子賦非空值但雙親為空 return ERROR else if valueNilT i21NilT i22Nil 給雙親賦空值但有葉子 不空 return ERROR T ivalue return OK TElemType Parent SqBiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：若 e 是 T 的非根結點，則返回它的雙親，否則返回＂空＂ int i if T 0Nil 空樹 return Nil for i1iMAX_TREE_SIZE1i if T ie 找到 e return T i121 return Nil 沒找到 e TElemType LeftChild SqBiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點。操作結果：返回 e 的左孩子。若 e 無左孩子，則返回 空 int i if T 0Nil 空樹 return Nil for i0iMAX_TREE_SIZE1i if T ie 找到 e return T i21 return Nil 沒找到 e TElemType RightChild SqBiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點。操作結果：返回 e 的右孩子。若 e 無右孩子，則返回 空 int i if T 0Nil 空樹 return Nil for i0iMAX_TREE_SIZE1i if T ie 找到 e return T i22 return Nil 沒找到 e TElemType LeftSibling SqBiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：返回 e 的左兄弟。若 e 是 T 的左孩子或無左兄弟，則返回＂空＂ int i if T 0Nil 空樹 return Nil for i1iMAX_TREE_SIZE1i if T iei20 找到 e 且其序號為偶數 是右孩子 return T i1 return Nil 沒找到 e TElemType RightSibling SqBiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：返回 e 的右兄弟。若 e 是 T 的右孩子或無右兄弟，則返回＂空＂ int i if T 0Nil 空樹 return Nil for i1iMAX_TREE_SIZE1i if T iei2 找到 e 且其序號為奇數 是左孩子 return T i1 return Nil 沒找到 e void Move SqBiTree qint jSqBiTree Tint i InsertChild 用到。加 把從 q 的 j 結點開始的子樹移為從 T 的 i 結點開始的子樹 if q 2j1Nil q 的左子樹不空 Move q2j1T2i1 把 q 的 j 結點的左子樹移為 T 的 i 結點的左子樹 if q 2j2Nil q 的右子樹不空 Move q2j2T2i2 把 q 的 j 結點的右子樹移為 T 的 i 結點的右子樹 T iq j 把 q 的 j 結點移為 T 的 i 結點 q jNil 把 q 的 j 結點置空 void InsertChild SqBiTree TTElemType pint LRSqBiTree c 初始條件：二叉樹 T 存在，p 是 T 中某個結點的值，LR 為 0 或 1，非空二叉樹 c 與 T 不相交且右子樹為空 操作結果：根據 LR 為 0 或 1 插入 c 為 T 中 p 結點的左或右子樹。p 結點的原有左或右子樹則成為 c 的右子樹 int jki0 for j0jint pow 2BiTreeDepth T1j 查詢 p 的序號 if T jp j 為 p 的序號 break k2j1LR k 為 p 的左或右孩子的序號 if T kNil p 原來的左或右孩子不空 Move TkT2k2 把從 T 的 k 結點開始的子樹移為從 k 結點的右子樹開始的子樹 Move ciTk 把從 c 的 i 結點開始的子樹移為從 T 的 k 結點開始的子樹 typedef int QElemType 設佇列元素型別為整型 序號 include c32h 鏈佇列 include bo32c 鏈佇列的基本操作 Status DeleteChild SqBiTree Tposition pint LR 初始條件：二叉樹 T 存在，p 指向 T 中某個結點，LR 為 1 或 0 操作結果：根據 LR 為 1 或 0，刪除 T 中 p 所指結點的左或右子樹 int i Status kOK 佇列不空的標誌 LinkQueue q InitQueue q 初始化佇列，用於存放待刪除的結點 iint pow 2plevel1porder2 將層、本層序號轉為矩陣的序號 if T iNil 此結點空 return ERROR ii21LR 待刪除子樹的根結點在矩陣中的序號 while k if T 2i1Nil 左結點不空 EnQueue q2i1 入隊左結點的序號 if T 2i2Nil 右結點不空 EnQueue q2i2 入隊右結點的序號 T iNil 刪除此結點 kDeQueue qi 佇列不空 return OK void VisitFuncTElemType 函式變數 void PreTraverse SqBiTree Tint e PreOrderTraverse 呼叫 VisitFunc T e if T 2e1Nil 左子樹不空 PreTraverse T2e1 if T 2e2Nil 右子樹不空 PreTraverse T2e2 void PreOrderTraverse SqBiTree Tvoid VisitTElemType 初始條件：二叉樹存在，Visit 是對結點操作的應用函式 操作結果：先序遍歷 T，對每個結點呼叫函式 Visit 一次且僅一次 VisitFuncVisit if BiTreeEmpty T 樹不空 PreTraverse T0 printf n void InTraverse SqBiTree Tint e InOrderTraverse 呼叫 if T 2e1Nil 左子樹不空 InTraverse T2e1 VisitFunc T e if T 2e2Nil 右子樹不空 InTraverse T2e2 void InOrderTraverse SqBiTree Tvoid VisitTElemType 初始條件：二叉樹存在，Visit 是對結點操作的應用函式 操作結果：中序遍歷 T，對每個結點呼叫函式 Visit 一次且僅一次 VisitFuncVisit if BiTreeEmpty T 樹不空 InTraverse T0 printf n void PostTraverse SqBiTree Tint e PostOrderTraverse 呼叫 if T 2e1Nil 左子樹不空 PostTraverse T2e1 if T 2e2Nil 右子樹不空 PostTraverse T2e2 VisitFunc T e void PostOrderTraverse SqBiTree Tvoid VisitTElemType 初始條件：二叉樹 T 存在，Visit 是對結點操作的應用函式 操作結果：後序遍歷 T，對每個結點呼叫函式 Visit 一次且僅一次 VisitFuncVisit if BiTreeEmpty T 樹不空 PostTraverse T0 printf n void LevelOrderTraverse SqBiTree Tvoid VisitTElemType 層序遍歷二叉樹 int iMAX_TREE_SIZE1j while T iNil i 找到最後一個非空結點的序號 for j0jij 從根結點起，按層序遍歷二叉樹 if T jNil Visit T j 只遍歷非空的結點 printf n void Print SqBiTree T 逐層、按本層序號輸出二叉樹 int jk position p TElemType e for j1jBiTreeDepth Tj printf 第 d 層j for k1kpow 2j1k plevelj porderk eValue Tp if eNil printf dform ke printf n 二叉連結串列儲存表示 在使用記錄或記憶體位址指標的程式設計語言中，二叉樹通常用樹結點結構來儲存。有時也包含指向唯一的父節點的指標。如果一個結點的子結點個數小於 2，一些子結點指標可能為空值，或者為特殊的哨兵結點。 使用連結串列能避免順序儲存浪費空間的問題，演演算法和結構相對簡單，但使用二叉連結串列，由於缺乏父鏈的指引，在找回父節點時需要重新掃描樹得知父節點的節點位址。 儲存結構 二叉樹的二叉連結串列儲存表示 typedef struct BiTNode TElemType data struct BiTNode lchildrchild 左右孩子指標 BiTNodeBiTree 基本操作 二叉樹的二叉連結串列儲存的基本操作 22 個 define ClearBiTree DestroyBiTree 清空二叉樹和銷毀二叉樹的操作一樣 includefunc63c 包括 InitBiTree 、DestroyBiTree 、PreOrderTraverse 和 InOrderTraverse 4 函式 void CreateBiTree BiTree T 演演算法 64：按先序次序輸入二叉樹中結點的值 可為字元型或整型，在主程中定義， 構造二叉鏈表表示的二叉樹 T。變數 Nil 表示空 子 樹。有改動 TElemType ch scanf formch if chNil 空 TNULL else TBiTree malloc sizeof BiTNode 生成根結點 if T exit OVERFLOW Tdatach CreateBiTree Tlchild 構造左子樹 CreateBiTree Trchild 構造右子樹 Status BiTreeEmpty BiTree T 初始條件：二叉樹 T 存在。操作結果：若 T 為空二叉樹，則返回 TRUE，否則 FALSE if T return FALSE else return TRUE int BiTreeDepth BiTree T 初始條件：二叉樹 T 存在。操作結果：返回 T 的深度 int ij if TNULL 如果 TNULL 這樣寫便於理解，當然也可以寫成 if（T） return 0 空樹深度為 0 if Tlchild iBiTreeDepth Tlchild i 為左子樹的深度 else i0 if Trchild jBiTreeDepth Trchild j 為右子樹的深度 else j0 return iji1j1 T 的深度為其左右子樹的深度中的大者 1 TElemType Root BiTree T 初始條件：二叉樹 T 存在。操作結果：返回 T 的根 if BiTreeEmpty T return Nil else return Tdata TElemType Value BiTree p 初始條件：二叉樹 T 存在，p 指向 T 中某個結點。操作結果：返回 p 所指結點的值 return pdata void Assign BiTree pTElemType value 給 p 所指結點賦值為 value pdatavalue typedef BiTree QElemType 設佇列元素為二叉樹的指標型別 includec32h 鏈佇列 includebo32c 鏈佇列的基本操作 TElemType Parent BiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：若 e 是 T 的非根結點，則返回它的雙親，否則返回＂空＂ LinkQueue q QElemType a if T 非空樹 InitQueue q 初始化佇列 EnQueue qT 樹根指標入隊 while QueueEmpty q 隊不空 DeQueue qa 出隊，佇列元素賦給 a if alchildalchilddataearchildarchilddatae 找到 e 是其左或右孩子 return adata 返回 e 的雙親的值 else 沒找到 e，則入隊其左右孩子指標 如果非空 if alchild EnQueue qalchild if archild EnQueue qarchild return Nil 樹空或沒找到 e BiTree Point BiTree TTElemType s 返回二叉樹 T 中指向元素值為 s 的結點的指標。另加 LinkQueue q QElemType a if T 非空樹 InitQueue q 初始化佇列 EnQueue qT 根指標入隊 while QueueEmpty q 隊不空 DeQueue qa 出隊，佇列元素賦給 a if adatas return a if alchild 有左孩子 EnQueue qalchild 入隊左孩子 if archild 有右孩子 EnQueue qarchild 入隊右孩子 return NULL TElemType LeftChild BiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點。操作結果：返回 e 的左孩子。若 e 無左孩子，則返回 空 BiTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aalchild T 中存在結點 e 且 e 存在左孩子 return alchilddata 返回 e 的左孩子的值 return Nil 其餘情況返回空 TElemType RightChild BiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點。操作結果：返回 e 的右孩子。若 e 無右孩子，則返回 空 BiTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aarchild T 中存在結點 e 且 e 存在右孩子 return archilddata 返回 e 的右孩子的值 return Nil 其餘情況返回空 TElemType LeftSibling BiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：返回 e 的左兄弟。若 e 是 T 的左孩子或無左兄弟，則返回＂空＂ TElemType a BiTree p if T 非空樹 aParent Te a 為 e 的雙親 if aNil 找到 e 的雙親 pPoint Ta p 為指向結點 a 的指標 if plchildprchildprchilddatae p 存在左右孩子且右孩子是 e return plchilddata 返回 p 的左孩子 e 的左兄弟 return Nil 其餘情況返回空 TElemType RightSibling BiTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：返回 e 的右兄弟。若 e 是 T 的右孩子或無右兄弟，則返回＂空＂ TElemType a BiTree p if T 非空樹 aParent Te a 為 e 的雙親 if aNil 找到 e 的雙親 pPoint Ta p 為指向結點 a 的指標 if plchildprchildplchilddatae p 存在左右孩子且左孩子是 e return prchilddata 返回 p 的右孩子 e 的右兄弟 return Nil 其餘情況返回空 Status InsertChild BiTree pint LRBiTree c 形參 T 無用 初始條件：二叉樹 T 存在，p 指向 T 中某個結點，LR 為 0 或 1，非空二叉樹 c 與 T 不相交且右子樹為空 操作結果：根據 LR 為 0 或 1，插入 c 為 T 中 p 所指結點的左或右子樹。p 所指結點的 原有左或右子樹則成為 c 的右子樹 if p p 不空 if LR0 crchildplchild plchildc else LR1 crchildprchild prchildc return OK return ERROR p 空 Status DeleteChild BiTree pint LR 形參 T 無用 初始條件：二叉樹 T 存在，p 指向 T 中某個結點，LR 為 0 或 1 操作結果：根據 LR 為 0 或 1，刪除 T 中 p 所指結點的左或右子樹 if p p 不空 if LR0 刪除左子樹 ClearBiTree plchild else 刪除右子樹 ClearBiTree prchild return OK return ERROR p 空 typedef BiTree SElemType 設棧元素為二叉樹的指標型別 includec31h 順序棧 includebo31c 順序棧的基本操作 void InOrderTraverse1 BiTree Tvoid VisitTElemType 採用二叉連結串列儲存結構，Visit 是對資料元素操作的應用函式。演演算法 63，有改動 中序遍歷二叉樹 T 的非遞迴演演算法 利用棧，對每個資料元素呼叫函式 Visit SqStack S InitStack S while TStackEmpty S if T 根指標進棧，遍歷左子樹 Push ST TTlchild else 根指標退棧，訪問根結點，遍歷右子樹 Pop ST Visit Tdata TTrchild printf n void InOrderTraverse2 BiTree Tvoid VisitTElemType 採用二叉連結串列儲存結構，Visit 是對資料元素操作的應用函式。演演算法 62，有改動 中序遍歷二叉樹 T 的非遞迴演演算法 利用棧，對每個資料元素呼叫函式 Visit SqStack S BiTree p InitStack S Push ST 根指標進棧 while StackEmpty S while GetTop Spp Push Splchild 向左走到盡頭 Pop Sp 空指標退棧 if StackEmpty S 訪問結點，向右一步 Pop Sp Visit pdata Push Sprchild printf n void PostOrderTraverse BiTree Tvoid VisitTElemType 初始條件：二叉樹 T 存在，Visit 是對結點操作的應用函式 操作結果：後序遞迴遍歷 T，對每個結點呼叫函式 Visit 一次且僅一次 if T T 不空 PostOrderTraverse TlchildVisit 先後序遍歷左子樹 PostOrderTraverse TrchildVisit 再後序遍歷右子樹 Visit Tdata 最後訪問根結點 void LevelOrderTraverse BiTree Tvoid VisitTElemType 初始條件：二叉樹 T 存在，Visit 是對結點操作的應用函式 操作結果：層序遞迴遍歷 T 利用佇列，對每個結點呼叫函式 Visit 一次且僅一次 LinkQueue q QElemType a if T InitQueue q 初始化佇列 q EnQueue qT 根指標入隊 while QueueEmpty q 佇列不空 DeQueue qa 出隊元素 指標 賦給 a Visit adata 訪問 a 所指結點 if alchildNULL a 有左孩子 EnQueue qalchild 入隊 a 的左孩子 if archildNULL a 有右孩子 EnQueue qarchild 入隊 a 的右孩子 printf n 三叉連結串列儲存表示 改進於二叉連結串列，增加父節點的指引，能更好地實現節點間的訪問，不過演演算法相對複雜。 當二叉樹用三叉鏈表表示時，有 N 個結點，就會有 N2 個空指標。 儲存結構 二叉樹的三叉連結串列儲存表示 typedef struct BiTPNode TElemType data struct BiTPNode parentlchildrchild 父、左右孩子指標 BiTPNodeBiPTree 基本操作 二叉樹的三叉連結串列儲存的基本操作 21 個 define ClearBiTree DestroyBiTree 清空二叉樹和銷毀二叉樹的操作一樣 void InitBiTree BiPTree T 操作結果：構造空二叉樹 T TNULL void DestroyBiTree BiPTree T 初始條件：二叉樹 T 存在。操作結果：銷毀二叉樹 T if T 非空樹 if Tlchild 有左孩子 DestroyBiTree Tlchild 銷毀左孩子子樹 if Trchild 有右孩子 DestroyBiTree Trchild 銷毀右孩子子樹 free T 釋放根結點 TNULL 空指標賦 0 void CreateBiTree BiPTree T 按先序次序輸入二叉樹中結點的值 可為字元型或整型，在主程中定義， 構造三叉鏈表表示的二叉樹 T TElemType ch scanf formch if chNil 空 TNULL else TBiPTree malloc sizeof BiTPNode 動態生成根結點 if T exit OVERFLOW Tdatach 給根結點賦值 TparentNULL 根結點無雙親 CreateBiTree Tlchild 構造左子樹 if Tlchild 有左孩子 TlchildparentT 給左孩子的雙親域賦值 CreateBiTree Trchild 構造右子樹 if Trchild 有右孩子 TrchildparentT 給右孩子的雙親域賦值 Status BiTreeEmpty BiPTree T 初始條件：二叉樹 T 存在。操作結果：若 T 為空二叉樹，則返回 TRUE，否則 FALSE if T return FALSE else return TRUE int BiTreeDepth BiPTree T 初始條件：二叉樹 T 存在。操作結果：返回 T 的深度 int ij if T return 0 空樹深度為 0 if Tlchild iBiTreeDepth Tlchild i 為左子樹的深度 else i0 if Trchild jBiTreeDepth Trchild j 為右子樹的深度 else j0 return iji1j1 T 的深度為其左右子樹的深度中的大者 1 TElemType Root BiPTree T 初始條件：二叉樹 T 存在。操作結果：返回 T 的根 if T return Tdata else return Nil TElemType Value BiPTree p 初始條件：二叉樹 T 存在，p 指向 T 中某個結點。操作結果：返回 p 所指結點的值 return pdata void Assign BiPTree pTElemType value 給 p 所指結點賦值為 value pdatavalue typedef BiPTree QElemType 設佇列元素為二叉樹的指標型別 includec32h 鏈佇列 includebo32c 鏈佇列的基本操作 BiPTree Point BiPTree TTElemType e 返回二叉樹 T 中指向元素值為 e 的結點的指標。加 LinkQueue q QElemType a if T 非空樹 InitQueue q 初始化佇列 EnQueue qT 根結點入隊 while QueueEmpty q 隊不空 DeQueue qa 出隊，佇列元素賦給 a if adatae return a if alchild 有左孩子 EnQueue qalchild 入隊左孩子 if archild 有右孩子 EnQueue qarchild 入隊右孩子 return NULL TElemType Parent BiPTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：若 e 是 T 的非根結點，則返回它的雙親，否則返回＂空＂ BiPTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aaT T 中存在結點 e 且 e 是非根結點 return aparentdata 返回 e 的雙親的值 return Nil 其餘情況返回空 TElemType LeftChild BiPTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點。操作結果：返回 e 的左孩子。若 e 無左孩子，則返回 空 BiPTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aalchild T 中存在結點 e 且 e 存在左孩子 return alchilddata 返回 e 的左孩子的值 return Nil 其餘情況返回空 TElemType RightChild BiPTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點。操作結果：返回 e 的右孩子。若 e 無右孩子，則返回 空 BiPTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aarchild T 中存在結點 e 且 e 存在右孩子 return archilddata 返回 e 的右孩子的值 return Nil 其餘情況返回空 TElemType LeftSibling BiPTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：返回 e 的左兄弟。若 e 是 T 的左孩子或無左兄弟，則返回＂空＂ BiPTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aaTaparentlchildaparentlchilda T 中存在結點 e 且 e 存在左兄弟 return aparentlchilddata 返回 e 的左兄弟的值 return Nil 其餘情況返回空 TElemType RightSibling BiPTree TTElemType e 初始條件：二叉樹 T 存在，e 是 T 中某個結點 操作結果：返回 e 的右兄弟。若 e 是 T 的右孩子或無右兄弟，則返回＂空＂ BiPTree a if T 非空樹 aPoint Te a 是結點 e 的指標 if aaTaparentrchildaparentrchilda T 中存在結點 e 且 e 存在右兄弟 return aparentrchilddata 返回 e 的右兄弟的值 return Nil 其餘情況返回空 Status InsertChild BiPTree pint LRBiPTree c 形參 T 無用 初始條件：二叉樹 T 存在，p 指向 T 中某個結點，LR 為 0 或 1，非空二叉樹 c 與 T 不相交且右子樹為空 操作結果：根據 LR 為 0 或 1，插入 c 為 T 中 p 所指結點的左或右子樹。p 所指結點 的原有左或右子樹則成為 c 的右子樹 if p p 不空 if LR0 crchildplchild if crchild c 有右孩子 p 原有左孩子 crchildparentc plchildc cparentp else LR1 crchildprchild if crchild c 有右孩子 p 原有右孩子 crchildparentc prchildc cparentp return OK return ERROR p 空 Status DeleteChild BiPTree pint LR 形參 T 無用 初始條件：二叉樹 T 存在，p 指向 T 中某個結點，LR 為 0 或 1 操作結果：根據 LR 為 0 或 1，刪除 T 中 p 所指結點的左或右子樹 if p p 不空 if LR0 刪除左子樹 ClearBiTree plchild else 刪除右子樹 ClearBiTree prchild return OK return ERROR p 空 void PreOrderTraverse BiPTree Tvoid VisitBiPTree 先序遞迴遍歷二叉樹 T if T Visit T 先訪問根結點 PreOrderTraverse TlchildVisit 再先序遍歷左子樹 PreOrderTraverse TrchildVisit 最後先序遍歷右子樹 void InOrderTraverse BiPTree Tvoid VisitBiPTree 中序遞迴遍歷二叉樹 T if T InOrderTraverse TlchildVisit 中序遍歷左子樹 Visit T 再訪問根結點 InOrderTraverse TrchildVisit 最後中序遍歷右子樹 void PostOrderTraverse BiPTree Tvoid VisitBiPTree 後序遞迴遍歷二叉樹 T if T PostOrderTraverse TlchildVisit 後序遍歷左子樹 PostOrderTraverse TrchildVisit 後序遍歷右子樹 Visit T 最後訪問根結點 void LevelOrderTraverse BiPTree Tvoid VisitBiPTree 層序遍歷二叉樹 T 利用佇列 LinkQueue q QElemType a if T InitQueue q EnQueue qT while QueueEmpty q DeQueue qa Visit a if alchildNULL EnQueue qalchild if archildNULL EnQueue qarchild 遍歷 我們經常希望訪問樹中的每一個結點並且檢視它的值。有很多常見的順序來訪問所有的結點，而且每一種都有有用的性質。 深度優先遍歷 在深度優先順序中，我們希望從根結點訪問最遠的結點。和圖的深度優先搜尋不同的是，不需記住訪問過的每一個結點，因為樹中不會有環。前序，中序和後序遍歷都是深度優先遍歷的特例。 前（先）序、中序、後序遍歷 遍歷二叉樹：L、D、R 分別表示遍歷左子樹、訪問根結點和遍歷右子樹，則先 根 序遍歷二叉樹的順序是 DLR，中 根 序遍歷二叉樹的順序是 LDR，後 根 序遍歷二叉樹的順序是 LRD。還有按層遍歷二叉樹。這些方法的時間複雜度都是 O n，n 為結點個數。 如果 T2 是由有序樹 T 轉換而來的二叉樹，那麼 T 中結點的前序就是 T2 中結點的前序，T 中結點的後序就是 T2 中結點的中序。任何一棵二叉樹的葉結點在先序、中序和後序遍歷中的相對次序不發改變。設 nm 為一棵二叉樹上的兩個結點，在中序遍歷時，n 在 m 前的條件是 n 在 m 的左方。前序序列和中序序列相同的二叉樹為空樹或任一結點均無左孩子的非空二叉樹；中序序列和後序序列相同的二叉樹為空樹或任一結點均無右孩子的非空二叉樹；前序序列和後序序列相同的二叉樹為空樹或僅有一個結點的二叉樹。 假設我們有一個包含值的 value 和指向兩個子結點的 left 和 right 的樹結點結構。我們可以寫出這樣的過程： visit node print nodevalue if nodeleft null then visit nodeleft if noderight null then visit noderight 這樣會用前序打印出樹中的值。在前序，每個結點在訪問它的子結點之前訪問。類似地，如果列印語句在最後，每個結點在訪問他的子節點之後訪問，樹中的值會用後序來列印。在這兩種情況中，左子樹中的值比右子樹中得值先列印。 visit node if nodeleft null then visit nodeleft print nodevalue if noderight null then visit noderight 最後，上面的中序遍歷，每個結點在訪問左子樹和右子樹之間訪問。這在遍歷二叉搜尋樹時很常用，因為它能用遞增的順序來遍歷所有的值。 為什麼呢？如果 n 是二叉搜尋樹的結點，那麼 n 的左子樹的所有結點的值都比 n 的值要小，而且 n 的右子樹的所有節點的值都比 n 的值要大。因此，如果我們順序遍歷左子樹，然後訪問 n，然後順序遍歷右子樹。我們就已經循序存取了整個樹。 後序遍歷虛擬碼如下： visit node if nodeleft null then visit nodeleft if noderight null then visit noderight print nodevalue 在這個二叉樹中， 前序遍歷的結果：M，G，D，B，A，C，F，E，J，H，I，K，L，S，P，O，N，Q，R，W，U，T，V，X，Z，Y 後序遍歷的結果：A，C，B，E，F，D，I，H，L，K，J，G，N，O，R，Q，P，T，V，U，Y，Z，X，W，S，M 中序遍歷的結果：A，B，C，D，E，F，G，H，I，J，K，L，M，N，O，P，Q，R，S，T，U，V，W，X，Y，Z 以上的遞迴演演算法使用與樹的高度成比例的棧空間。如果我們在每個結點中儲存指向父結點的指標，那樣可以使用反覆運算演演算法，只使用常數空間實現所有這些遍歷。然而，指向父結點的指標佔用更多的空間。這只在需要指向父節點的指標或棧空間有限時才使用。例如， 這是一個中序遍歷的反覆運算演演算法： visit root prev null current root next null while current null if prev currentparent prev current next currentleft if next null or prev currentleft print currentvalue prev current next currentright if next null or prev currentright prev current next currentparent current next FileBitreeJPG 用二叉樹表示下述運算式：abcdef 先序遍歷的序列是：abcdef 中序遍歷的序列是：abcdef 後序遍歷的序列是：abcdef 廣度優先遍歷 和深度優先遍歷不同，廣度優先遍歷會先訪問離根節點最近的節點。二叉樹的廣度優先遍歷又稱按層次遍歷。演演算法藉助佇列實現。 轉換自多叉樹 一般有序樹可對映為二叉樹，但反之未必成立。 n 叉樹轉換為二叉樹的方法：二叉樹中結點 x 的左子結點為 n 叉樹中結點 x 的左子結點；二叉樹中結點 x 的右子結點為 n 叉樹中結點 x 的第一個右邊的同級結點 y。 二叉樹當且僅當根節點沒有右子結點時可轉換為 n 叉樹。 例如，在左邊的樹中，A 有 6 個子結點 BCDEFG。它能被轉換成右邊的二叉樹。 將一棵樹轉換為二叉樹的方法： 在兄弟之間加一連線； 對每個結點，除了其左孩子外，去除其與其餘孩子之間的聯絡； 以樹的根結點為軸心，將整樹順時針轉 45 度。 樹的二叉連結串列標記法（孩子兄弟標記法） 樹的二叉連結串列標記法（孩子兄弟標記法）是樹和二叉樹轉換的媒介。 儲存結構 樹的二叉連結串列 孩子 兄弟 儲存表示 typedef struct CSNode TElemType data struct CSNode firstchildnextsibling CSNodeCSTree 基本操作 樹的二叉連結串列 孩子 兄弟 儲存的基本操作 17 個 define ClearTree DestroyTree 二者操作相同 includefunc62c 包括 PreOrderTraverse void InitTree CSTree T 操作結果：構造空樹 T TNULL void DestroyTree CSTree T 初始條件：樹 T 存在。操作結果：銷毀樹 T if T if Tfirstchild T 有長子 DestroyTree Tfirstchild 銷毀 T 的長子為根結點的子樹 if Tnextsibling T 有下一個兄弟 DestroyTree Tnextsibling 銷毀 T 的下一個兄弟為根結點的子樹 free T 釋放根結點 TNULL typedef CSTree QElemType 定義佇列元素型別 includec32h 定義 LinkQueue 型別 鏈佇列 includebo32c LinkQueue 型別的基本操作 void CreateTree CSTree T 構造樹 T char c 20 臨時存放孩子結點 設不超過 20 個 的值 CSTree pp1 LinkQueue q int il InitQueue q printf 請輸入根結點 字元型，空格為空 scanf ccc 0 if c 0Nil 非空樹 TCSTree malloc sizeof CSNode 建立根結點 Tdatac 0 TnextsiblingNULL EnQueue qT 入隊根結點的指標 while QueueEmpty q 隊不空 DeQueue qp 出隊一個結點的指標 printf 請按長幼順序輸入結點 c 的所有孩子pdata gets c lstrlen c if l0 有孩子 p1pfirstchildCSTree malloc sizeof CSNode 建立長子結點 p1datac 0 for i1ili p1nextsiblingCSTree malloc sizeof CSNode 建立下一個兄弟結點 EnQueue qp1 入隊上一個結點 p1p1nextsibling p1datac i p1nextsiblingNULL EnQueue qp1 入隊最後一個結點 else pfirstchildNULL 長子指標為空 else TNULL 空樹 Status TreeEmpty CSTree T 初始條件：樹 T 存在。操作結果：若 T 為空樹，則返回 TURE，否則返回 FALSE if T T 不空 return FALSE else return TRUE int TreeDepth CSTree T 初始條件：樹 T 存在。操作結果：返回 T 的深度 CSTree p int depthmax0 if T 樹空 return 0 if Tfirstchild 樹無長子 return 1 for pTfirstchildpppnextsibling 求子樹深度的最大值 depthTreeDepth p if depthmax maxdepth return max1 樹的深度 子樹深度最大值 1 TElemType Value CSTree p 返回 p 所指結點的值 return pdata TElemType Root CSTree T 初始條件：樹 T 存在。操作結果：返回 T 的根 if T return Value T else return Nil CSTree Point CSTree TTElemType s 返回二叉連結串列 孩子 兄弟 樹 T 中指向元素值為 s 的結點的指標。另加 LinkQueue q QElemType a if T 非空樹 InitQueue q 初始化佇列 EnQueue qT 根結點入隊 while QueueEmpty q 隊不空 DeQueue qa 出隊，佇列元素賦給 a if adatas return a if afirstchild 有長子 EnQueue qafirstchild 入隊長子 if anextsibling 有下一個兄弟 EnQueue qanextsibling 入隊下一個兄弟 return NULL Status Assign CSTree TTElemType cur_eTElemType value 初始條件：樹 T 存在，cur_e 是樹 T 中結點的值。操作結果：改 cur_e 為 value CSTree p if T 非空樹 pPoint Tcur_e p 為 cur_e 的指標 if p 找到 cur_e pdatavalue 賦新值 return OK return ERROR 樹空或沒找到 TElemType Parent CSTree TTElemType cur_e 初始條件：樹 T 存在，cur_e 是 T 中某個結點 操作結果：若 cur_e 是 T 的非根結點，則返回它的雙親，否則函式值為＂空＂ CSTree pt LinkQueue q InitQueue q if T 樹非空 if Value Tcur_e 根結點值為 cur_e return Nil EnQueue qT 根結點入隊 while QueueEmpty q DeQueue qp if pfirstchild p 有長子 if pfirstchilddatacur_e 長子為 cur_e return Value p 返回雙親 tp 雙親指標賦給 t ppfirstchild p 指向長子 EnQueue qp 入隊長子 while pnextsibling 有下一個兄弟 ppnextsibling p 指向下一個兄弟 if Value pcur_e 下一個兄弟為 cur_e return Value t 返回雙親 EnQueue qp 入隊下一個兄弟 return Nil 樹空或沒找到 cur_e TElemType LeftChild CSTree TTElemType cur_e 初始條件：樹 T 存在，cur_e 是 T 中某個結點 操作結果：若 cur_e 是 T 的非葉子結點，則返回它的最左孩子，否則返回＂空＂ CSTree f fPoint Tcur_e f 指向結點 cur_e if fffirstchild 找到結點 cur_e 且結點 cur_e 有長子 return ffirstchilddata else return Nil TElemType RightSibling CSTree TTElemType cur_e 初始條件：樹 T 存在，cur_e 是 T 中某個結點 操作結果：若 cur_e 有右兄弟，則返回它的右兄弟，否則返回＂空＂ CSTree f fPoint Tcur_e f 指向結點 cur_e if ffnextsibling 找到結點 cur_e 且結點 cur_e 有右兄弟 return fnextsiblingdata else return Nil 樹空 Status InsertChild CSTree TCSTree pint iCSTree c 初始條件：樹 T 存在，p 指向 T 中某個結點，1ip 所指結點的度 1，非空樹 c 與 T 不相交 操作結果：插入 c 為 T 中 p 結點的第 i 棵子樹 因為 p 所指結點的位址不會改變，故 p 不需是參考型別 int j if T T 不空 if i1 插入 c 為 p 的長子 cnextsiblingpfirstchild p 的原長子現是 c 的下一個兄弟 c 本無兄弟 pfirstchildc else 找插入點 ppfirstchild 指向 p 的長子 j2 while pij ppnextsibling j if ji 找到插入位置 cnextsiblingpnextsibling pnextsiblingc else p 原有孩子數小於 i1 return ERROR return OK else T 空 return ERROR Status DeleteChild CSTree TCSTree pint i 初始條件：樹 T 存在，p 指向 T 中某個結點，1ip 所指結點的度 操作結果：刪除 T 中 p 所指結點的第 i 棵子樹 因為 p 所指結點的位址不會改變，故 p 不需是參考型別 CSTree b int j if T T 不空 if i1 刪除長子 bpfirstchild pfirstchildbnextsibling p 的原次子現是長子 bnextsiblingNULL DestroyTree b else 刪除非長子 ppfirstchild p 指向長子 j2 while pij ppnextsibling j if ji 找到第 i 棵子樹 bpnextsibling pnextsiblingbnextsibling bnextsiblingNULL DestroyTree b else p 原有孩子數小於 i return ERROR return OK else return ERROR void PostOrderTraverse CSTree Tvoid VisitTElemType 後根遍歷孩子 兄弟二叉連結串列結構的樹 T CSTree p if T if Tfirstchild 有長子 PostOrderTraverse TfirstchildVisit 後根遍歷長子子樹 pTfirstchildnextsibling p 指向長子的下一個兄弟 while p PostOrderTraverse pVisit 後根遍歷下一個兄弟子樹 ppnextsibling p 指向再下一個兄弟 Visit Value T 最後訪問根結點 void LevelOrderTraverse CSTree Tvoid VisitTElemType 層序遍歷孩子 兄弟二叉連結串列結構的樹 T CSTree p LinkQueue q InitQueue q if T Visit Value T 先訪問根結點 EnQueue qT 入隊根結點的指標 while QueueEmpty q 隊不空 DeQueue qp 出隊一個結點的指標 if pfirstchild 有長子 ppfirstchild Visit Value p 訪問長子結點 EnQueue qp 入隊長子結點的指標 while pnextsibling 有下一個兄弟 ppnextsibling Visit Value p 訪問下一個兄弟 EnQueue qp 入隊兄弟結點的指標 線索二叉樹 線索二叉樹（，保留遍歷時結點在任一序列的前驅和後繼的資訊）：若結點有左子樹，則其 lchild 域指示其左孩子，否則令 lchild 域指示其前驅；若結點有右子樹，則其 rchild 域指示其右孩子，否則令 rchild 指示其後繼。還需在結點結構中增加兩個標誌域 LTag 和 RTag。LTag0 時，lchild 域指示結點的左孩子，LTag1 時，lchild 域指示結點的前驅；RTag0 時，rchild 域指示結點的右孩子，RTag1 時，rchild 域指示結點的後繼。以這種結點結構構成的二叉連結串列作為二叉樹的儲存結構，叫做線索連結串列，其中指向結點前驅和後繼的指標叫做線索，加上線索的二叉樹稱為線索二叉樹。對二叉樹以某種次序遍歷使其變為線索二叉樹的過程叫做線索化。若對二叉樹進行中序遍歷，則所得的線索二叉樹稱為中序線索二叉樹，線索連結串列稱為為中序線索連結串列。線索二叉樹是一種物理結構。 在中序線索樹找結點後繼的規律是：若其右標誌為 1，則右鏈為線索，指示其後繼，否則遍歷其右子樹時訪問的第一個結點（右子樹最左下的結點）為其後繼；找結點前驅的規律是：若其左標誌為 1，則左鏈為線索，指示其前驅，否則遍歷左子樹時最後訪問的一個結點（左子樹中最右下的結點）為其前驅。 在後序線索樹中找到結點的後繼分三種情況： 若結點是二叉樹的根，則其後繼為空； 若結點是其雙親的右孩子，或是其雙親的左孩子且其雙親沒有右子樹，則其後繼即為雙親結點； 若結點是其雙親的左孩子，且其雙親有右子樹，則其後繼為雙親右子樹上按後序遍歷列出的第一個結點。 二叉線索儲存表示 儲存結構 二叉樹的二叉線索儲存表示：線上索連結串列上新增一個頭結點，並令其 lchild 域的指標指向二叉樹的根結點，其 rchild 域的指標指向中序遍歷時訪問的最後一個結點。令二叉樹中序序列中的第一個結點的 lchild 域指標和最後一個結點的 rchild 域的指標均指向頭結點，這樣就建立了一個雙向線索連結串列。二叉樹常採用二叉連結串列方式儲存。 二叉樹的二叉線索儲存表示 typedef enum LinkThread PointerTag Link 0：指標，Thread 1：線索 typedef struct BiThrNode TElemType data struct BiThrNode lchildrchild 左右孩子指標 PointerTag LTagRTag 左右標誌 BiThrNodeBiThrTree 基本操作 二叉樹的二叉線索儲存的基本操作 void CreateBiThrTree BiThrTree T 按先序輸入線索二叉樹中結點的值，構造線索二叉樹 T。0 整型 空格 字元型 表示空結點 TElemType ch scanf formch if chNil TNULL else TBiThrTree malloc sizeof BiThrNode 生成根結點 先序 if T exit OVERFLOW Tdatach 給根結點賦植 CreateBiThrTree Tlchild 遞迴構造左子樹 if Tlchild 有左孩子 TLTagLink 給左標誌賦值 指標 CreateBiThrTree Trchild 遞迴構造右子樹 if Trchild 有右孩子 TRTagLink 給右標誌賦值 指標 BiThrTree pre 全域變數，始終指向剛剛訪問過的結點 void InThreading BiThrTree p 透過中序遍歷進行中序線索化，線索化之後 pre 指向最後一個結點。演演算法 67 if p 線索二叉樹不空 InThreading plchild 遞迴左子樹線索化 if plchild 沒有左孩子 pLTagThread 左標誌為線索 前驅 plchildpre 左孩子指標指向前驅 if pre prerchild 前驅不為空並且前驅沒有右孩子 preRTagThread 前驅的右標誌為線索 後繼 prerchildp 前驅右孩子指標指向其後繼 當前結點 p prep 保持 pre 指向 p 的前驅 InThreading prchild 遞迴右子樹線索化 void InOrderThreading BiThrTree ThrtBiThrTree T 中序遍歷二叉樹 T，並將其中序線索化，Thrt 指向頭結點。演演算法 66 ThrtBiThrTree malloc sizeof BiThrNode if Thrt 生成頭結點不成功 exit OVERFLOW ThrtLTagLink 建頭結點，左標誌為指標 ThrtRTagThread 右標誌為線索 ThrtrchildThrt 右指標回指 if T 若二叉樹空，則左指標回指 ThrtlchildThrt else ThrtlchildT 頭結點的左指標指向根結點 preThrt pre 前驅 的初值指向頭結點 InThreading T 中序遍歷進行中序線索化，pre 指向中序遍歷的最後一個結點 prerchildThrt 最後一個結點的右指標指向頭結點 preRTagThread 最後一個結點的右標誌為線索 Thrtrchildpre 頭結點的右指標指向中序遍歷的最後一個結點 void InOrderTraverse_Thr BiThrTree Tvoid VisitTElemType 中序遍歷線索二叉樹 T 頭結點 的非遞迴演演算法。演演算法 65 BiThrTree p pTlchild p 指向根結點 while pT 空樹或遍歷結束時，pT while pLTagLink 由根結點一直找到二叉樹的最左結點 pplchild Visit pdata 訪問此結點 while pRTagThreadprchildT prchild 是線索 後繼，且不是遍歷的最後一個結點 pprchild Visit pdata 訪問後繼結點 pprchild 若 prchild 不是線索 是右孩子，p 指向右孩子，返回迴圈， 找這棵子樹中序遍歷的第 1 個結點 void PreThreading BiThrTree p PreOrderThreading 呼叫的遞迴函式 if prerchild p 的前驅沒有右孩子 prerchildp p 前驅的後繼指向 p preRTagThread pre 的右孩子為線索 if plchild p 沒有左孩子 pLTagThread p 的左孩子為線索 plchildpre p 的左孩子指向前驅 prep 移動前驅 if pLTagLink p 有左孩子 PreThreading plchild 對 p 的左孩子遞迴呼叫 preThreading if pRTagLink p 有右孩子 PreThreading prchild 對 p 的右孩子遞迴呼叫 preThreading void PreOrderThreading BiThrTree ThrtBiThrTree T 先序線索化二叉樹 T，頭結點的右指標指向先序遍歷的最後 1 個結點 ThrtBiThrTree malloc sizeof BiThrNode if Thrt 生成頭結點 exit OVERFLOW ThrtLTagLink 頭結點的左指標為孩子 ThrtRTagThread 頭結點的右指標為線索 ThrtrchildThrt 頭結點的右指標指向自身 if T 空樹 ThrtlchildThrt 頭結點的左指標也指向自身 else 非空樹 ThrtlchildT 頭結點的左指標指向根結點 preThrt 前驅為頭結點 PreThreading T 從頭結點開始先序遞迴線索化 prerchildThrt 最後一個結點的後繼指向頭結點 preRTagThread Thrtrchildpre 頭結點的後繼指向最後一個結點 void PreOrderTraverse_Thr BiThrTree Tvoid VisitTElemType 先序遍歷線索二叉樹 T 頭結點 的非遞迴演演算法 BiThrTree pTlchild p 指向根結點 while pT p 沒指向頭結點 遍歷的最後 1 個結點的後繼指向頭結點 Visit pdata 訪問根結點 if pLTagLink p 有左孩子 pplchild p 指向左孩子 後繼 else p 無左孩子 pprchild p 指向右孩子或後繼 void PostThreading BiThrTree p PostOrderThreading 呼叫的遞迴函式 if p p 不空 PostThreading plchild 對 p 的左孩子遞迴呼叫 PostThreading PostThreading prchild 對 p 的右孩子遞迴呼叫 PostThreading if plchild p 沒有左孩子 pLTagThread p 的左孩子為線索 plchildpre p 的左孩子指向前驅 if prerchild p 的前驅沒有右孩子 preRTagThread p 前驅的右孩子為線索 prerchildp p 前驅的後繼指向 p prep 移動前驅 void PostOrderThreading BiThrTree ThrtBiThrTree T 後序遞迴線索化二叉樹 ThrtBiThrTree malloc sizeof BiThrNode if Thrt 生成頭結點 exit OVERFLOW ThrtLTagLink 頭結點的左指標為孩子 ThrtRTagThread 頭結點的右指標為線索 if T 空樹 ThrtlchildThrtrchildThrt 頭結點的左右指標指向自身 else 非空樹 ThrtlchildThrtrchildT 頭結點的左右指標指向根結點 最後一個結點 preThrt 前驅為頭結點 PostThreading T 從頭結點開始後序遞迴線索化 if preRTagLink 最後一個結點沒有右孩子 prerchildThrt 最後一個結點的後繼指向頭結點 preRTagThread void DestroyBiTree BiThrTree T DestroyBiThrTree 呼叫的遞迴函式，T 指向根結點 if T 非空樹 if TLTag0 有左孩子 DestroyBiTree Tlchild 銷毀左孩子子樹 if TRTag0 有右孩子 DestroyBiTree Trchild 銷毀右孩子子樹 free T 釋放根結點 TNULL 空指標賦 0 void DestroyBiThrTree BiThrTree Thrt 初始條件：線索二叉樹 Thrt 存在。操作結果：銷毀線索二叉樹 Thrt if Thrt 頭結點存在 if Thrtlchild 根結點存在 DestroyBiTree Thrtlchild 遞迴銷毀頭結點 lchild 所指二叉樹 free Thrt 釋放頭結點 ThrtNULL 線索二叉樹 Thrt 指標賦 0 外部連結 binary trees entry in the FindStat 資料庫 Gamedevnet introduction on binary trees 二叉樹歸納證明 Balanced binary search tree on array How to create bottomup an Ahnentafel list or a balanced binary search tree on array Binary trees and Implementation of the same with working code examples