二元樹是資料結構的核心主題,其遞迴特性使得大多數操作(建立、遍歷、搜尋、刪除)皆以遞迴實作最為自然。本文提供一個完整、可編譯執行的 C 語言二元樹基本操作實作,涵蓋初始化、建立、清除、深度計算、節點搜尋、插入、刪除子樹、尋找父節點/左子節點/左兄弟等核心功能。
#define MAX 100
#define ERROR 0
#define OK 1
#ifndef Type
typedef char Type; // 節點資料型別,預設為 char
#endif
typedef struct Bitree {
Type data;
struct Bitree *lchild;
struct Bitree *rchild;
} BitNode, *BiTree;
int InitBiTree(BiTree *T) {
*T = NULL;
return OK;
}
關鍵點:傳遞 BiTree*(指向指標的指標),以便在函數內修改呼叫端的樹根指標。
int CreatBiTree(BiTree *T) {
Type ch;
scanf("%c", &ch);
if (ch == ' ') {
*T = NULL;
} else {
*T = (BiTree)malloc(sizeof(BitNode));
(*T)->data = ch;
CreatBiTree(&(*T)->lchild);
CreatBiTree(&(*T)->rchild);
}
return OK;
}
int ClearBiTree(BiTree *T) {
if ((*T)->lchild) ClearBiTree(&(*T)->lchild);
if ((*T)->rchild) ClearBiTree(&(*T)->rchild);
if ((*T)->lchild == NULL && (*T)->rchild == NULL) {
free(*T);
*T = NULL;
}
return OK;
}
int BiTreeEmpty(BiTree T) {
return (T == NULL) ? OK : ERROR;
}
int BiTreeDepth(BiTree T) {
if (T == NULL) return 0;
int hl = BiTreeDepth(T->lchild);
int hr = BiTreeDepth(T->rchild);
return (hl > hr ? hl : hr) + 1;
}
BitNode Root(BiTree T) {
if (T == NULL) { printf("No Root"); exit(0); }
return *T;
}
int InserInc(BiTree *T, Type e) {
BiTree temp = (BiTree)malloc(sizeof(BitNode));
temp->data = e; temp->lchild = temp->rchild = NULL;
if (*T == NULL) { *T = temp; return OK; }
if (e < (*T)->data) return InserInc(&(*T)->lchild, e);
else return InserInc(&(*T)->rchild, e);
}
BiTree Search(BiTree T, Type val) {
if (T == NULL) return NULL;
if (T->data == val) return T;
BiTree res = Search(T->lchild, val);
return res ? res : Search(T->rchild, val);
}
int DeleteChild(BiTree *T, BiTree target, int flag) {
BiTree tar = Search(*T, target->data);
if (!tar) return ERROR;
if (flag == 0) { ClearBiTree(&tar->lchild); tar->lchild = NULL; }
else { ClearBiTree(&tar->rchild); tar->rchild = NULL; }
return OK;
}
// 父節點
BiTree Parent(BiTree T, Type e) {
if (!T) return NULL;
if ((T->lchild && T->lchild->data == e) || (T->rchild && T->rchild->data == e)) return T;
BiTree p = Parent(T->lchild, e);
return p ? p : Parent(T->rchild, e);
}
// 左子節點
BiTree LeftChild(BiTree T, Type e) {
if (!T) return NULL;
if (T->data == e) return T->lchild;
BiTree res = LeftChild(T->lchild, e);
return res ? res : LeftChild(T->rchild, e);
}
// 左兄弟(右子樹的左兄弟是左子樹根)
BiTree LeftSibling(BiTree T, Type e) {
if (!T->lchild || !T->rchild) return NULL;
if (T->lchild->data == e) return T->rchild;
BiTree res = LeftSibling(T->lchild, e);
return res ? res : LeftSibling(T->rchild, e);
}
int main() {
BiTree T; BitNode root; BiTree temp;
CreatBiTree(&T); // 輸入範例:A B C D (空格代表空節點)
// 測試各功能...
temp = LeftSibling(T, 'a');
return 0;
}
BiTree* 參數,確保遞迴過程中能正確更新父節點的子指標。ClearBiTree 採後序遍歷釋放節點,避免記憶體洩漏。OK/ERROR 回傳碼,便於呼叫端檢查。Type 巨集可輕鬆切換節點資料型別(int、float、結構體等)。使用 GCC 編譯:gcc btree.c -o btree,執行時依提示輸入前序序列(如 AB C ),即可驗證各項功能。