書籍資訊

  • 書名:《圖解演算法:使用 C#》
  • 類型:二叉樹與相關延伸結構整理

這篇在講什麼

這一篇圍繞在二叉樹,整理了幾個層次:

  • 二叉樹的基本型態
  • 如何表示二叉樹
  • 常見遍歷方式
  • 二叉搜尋樹
  • 平衡樹、霍夫曼樹、線索二叉樹等延伸概念

二叉樹的基本型態

二叉樹的意思很直接:

  • 每個節點最多只有兩個子節點
  • 通常分成左子樹與右子樹

常見類型包括:

  • 滿二叉樹 Fully Binary Tree
  • 完全二叉樹 Complete Binary Tree
  • 斜樹 Skewed Binary Tree
  • 嚴格二叉樹 Strictly Binary Tree

這些名詞的意義,在於幫助你判斷:

  • 結構是否規整
  • 高度是否容易失控
  • 適合用哪種儲存方式

怎麼表示二叉樹

陣列表示法

如果樹夠規整,尤其接近完全二叉樹,可以直接用陣列表示。

常見索引關係是:

  • 父節點在 i
  • 左子節點在 2 * i
  • 右子節點在 2 * i + 1

這種方式的好處是簡單,但缺點是:

  • 樹一旦不平衡,空洞會很多
  • 斜樹時會浪費大量空間

節點指標表示法

更一般的做法是每個節點保存:

  • 左子節點
  • 右子節點

這種表示法更靈活,也是實務上最常見的形式。

二叉樹遍歷

遍歷的本質是:

  • 你打算用什麼順序拜訪所有節點

三種經典遞迴順序是:

  • 前序:根 -> 左 -> 右
  • 中序:左 -> 根 -> 右
  • 後序:左 -> 右 -> 根

其中最常被拿來講性質的是中序遍歷,因為對二叉搜尋樹來說,中序遍歷會得到有序結果。

public static void InOrder(TreeNode node)
{
    if (node == null)
    {
        return;
    }

    InOrder(node.left);
    Console.WriteLine(node.val);
    InOrder(node.right);
}

二叉搜尋樹 BST

二叉搜尋樹 Binary Search Tree 的核心規則是:

  • 左子樹所有值都比根小
  • 右子樹所有值都比根大

這讓搜尋、插入、刪除都能利用比較結果,一路往左或往右縮小範圍。

它的價值在於:

  • 平均情況下查找效率不錯
  • 中序遍歷天然有序

但問題也很典型:

  • 如果資料插入順序太差,樹可能一路歪掉
  • 一歪就會接近鏈結串列

刪除節點時要想什麼

BST 刪除最常分三種情況:

  • 刪葉節點:直接刪
  • 只有一個子節點:讓父節點接過去
  • 有兩個子節點:找前驅或後繼來補位

這裡最重要的不是背步驟,而是維持 BST 性質不能壞掉。

線索樹、延伸二叉樹、霍夫曼樹

線索二叉樹

線索二叉樹的目的是善用原本為 null 的指標,讓遍歷更方便。
它偏向資料結構教材中的經典技巧,重點在節點關係的重新利用。

延伸二叉樹

延伸二叉樹會把原本的空子節點位置也視為一種外部節點,方便做理論分析,例如:

  • 外部路徑長度
  • 內部路徑長度

霍夫曼樹

霍夫曼樹 Huffman Tree 的重點是加權路徑長最小。
它常用在:

  • 最佳化編碼
  • 壓縮問題

平衡樹與 AVL

BST 最大的問題是會失衡。
AVL 樹就是為了解決這件事而出現的。

它要求:

  • 每個節點左右子樹高度差不能太大

這樣可以避免樹退化,讓搜尋、插入、刪除都維持比較穩定的效率。

所以 AVL 的核心不是「很會轉」,而是:

  • 用旋轉維持高度平衡

我自己的整理

二叉樹這一篇的重點,其實可以壓成三句話:

  • 樹的結構會影響操作成本
  • 遍歷順序會影響你看到的結果
  • 搜尋樹如果不平衡,優勢就會消失

後面那些延伸結構,都是在補二叉樹的不同弱點:

  • 線索樹在補遍歷成本
  • 霍夫曼樹在補加權路徑長
  • AVL 在補平衡問題

先記住的重點

  • 二叉樹是每個節點最多兩個子節點的樹
  • 中序遍歷在 BST 上會得到有序序列
  • BST 的效率仰賴結構不要失衡
  • 刪除 BST 節點時,要先判斷子節點情況
  • AVL 的重點是維持高度平衡,不讓樹退化