廣義樹與二元樹最大不同在於「節點度數不固定」,每個節點可擁有 0 到 N 個子節點。本文延續基礎篇,完善 GeneralTree 類別的核心功能:索引器、相等比較、葉節點判斷等。
using System;
using System.Collections;
namespace DataStructure
{
public class GeneralTree : Tree
{
private object _key;
private uint _degree;
private readonly ArrayList _treeList = new ArrayList();
public GeneralTree(object key)
{
_key = key;
_degree = 0;
}
// 核心屬性
public override object Key => _key;
public override uint Degree => _degree;
// 空樹判斷:廣義樹一旦建立即非空
public override bool IsEmpty() => false;
// 葉節點判斷:度數為 0 即為葉節點
public override bool IsLeaf() => _degree == 0;
// 索引器:存取子樹
public override Tree this[uint index]
{
get
{
if (index >= _degree) throw new ArgumentOutOfRangeException(nameof(index));
return (Tree)_treeList[(int)index];
}
set => _treeList[(int)index] = value;
}
// 掛載子樹
public virtual void AttachSubtree(GeneralTree subtree)
{
_treeList.Add(subtree);
_degree++;
}
// 卸載子樹
public virtual GeneralTree DetachSubtree(GeneralTree subtree)
{
_treeList.Remove(subtree);
_degree--;
return subtree;
}
// 相等比較:比較 Key、Degree 以及子樹結構
public override bool Equals(object obj)
{
if (!base.Equals(obj)) return false;
var other = (GeneralTree)obj;
return Equals(_key, other._key) &&
_degree == other._degree &&
Equals(_treeList, other._treeList);
}
public override int GetHashCode() => HashCode.Combine(_key, _degree, _treeList);
}
}
var root = new GeneralTree("Root");
var child1 = new GeneralTree("Child1");
var child2 = new GeneralTree("Child2");
var grandChild = new GeneralTree("GrandChild");
child1.AttachSubtree(grandChild);
root.AttachSubtree(child1);
root.AttachSubtree(child2);
// 遍歷
Console.WriteLine($"Root: {root.Key}, Degree: {root.Degree}");
for (uint i = 0; i < root.Degree; i++)
{
var child = (GeneralTree)root[i];
Console.WriteLine($" Child: {child.Key}, IsLeaf: {child.IsLeaf()}");
}
ArrayList 為非泛型,涉及裝箱/拆箱。.NET 2.0+ 建議改用 List<GeneralTree>。廣義樹是表達層級資料 (如組織架構、檔案系統、AST) 的自然模型。掌握其 C# 實作細節,有助於建構靈活的樹形資料處理元件。