【資料結構-樹】二叉樹的相關演算法
阿新 • • 發佈:2022-12-13
目錄
1 計算二叉樹中雙分支結點的個數
假設二叉樹採用二叉連結串列儲存,試設計一個演算法,計算一棵給定二叉樹的所有雙分支結點個數。
int count = 0; void Degree2 (BiTree T){ if (T != NULL){ Degree2(T->lchild); Degree2(T->rchild); if ((T->lchild != NULL) && (T->rchild != NULL)) count++; } }
2 交換二叉樹中所有左右子樹
編寫一個把樹 B 中所有結點的左、右子樹進行交換的函式。
void SwapNodeChild (BiTree T){
if (T->lchild != NULL)
SwapNodeChild(T->lchild);
if (T->rchild != NULL)
SwapNodeChild(T->rchild);
Swap(T->lchild, T->rchild);
}
3 求先序遍歷第 k 個元素
設計一個演算法,求先序遍歷序列中第 k 個結點的值。
int i = 1; int PreOrder (BiTree T, int k){ if (T != NULL){ if (i == k) return T->data; i++; PreOrder(T->lchild, k); PreOrder(T->rchild, k); } }
4 刪去值為 x 的子樹
對於樹中每個元素值為 x 的結點,刪去以它為根的子樹,並釋放相應的空間。
void Delete (BiTree T){ // 找到元素值為 x 的結點後,遞迴刪去它的左子樹和右子樹 if (T != NULL){ Delete(T->lchild); Delete(T->rchild); free(T); } } void Find (BiTree T, int x){ if (T != NULL){ if (T->data == x){ // 若找到元素值為 x 的結點 Delete(T); // 開始遞迴刪去它的左子樹和右子樹 return; } else{ // 若不是元素值為 x 的結點 Find(T->lchild, x); // 繼續找左子樹中有無元素值為 x 的結點 Find(T->rchild, x); // 繼續找右子樹中有無元素值為 x 的結點 } } }
5 計算二叉樹的帶權路徑長度(WPL)
二叉樹的帶權路徑長度(WPL)是二叉樹中所有葉結點的帶權路徑長度之和。給定一棵二叉樹 T,採用二叉連結串列儲存結點結構為
left | weight | right |
---|---|---|
左子樹指標域 | 權值 | 右子樹指標域 |
其中葉結點的 weight 域儲存該結點的非負權值,設 root 為指向 T 的根結點的指標,請設計求 T 的 WPL 的演算法。
演算法的核心思想是先序遍歷 + 計算層數,程式碼如下:
int WPL;
void WPL_PreOrder (BiTree T, int level){
if (T != NULL){
if ((T->lchild != NULL) && (T->rchild != NULL))
WPL = WPL + T->weight * level;
else if ((T->lchild != NULL) && (T->rchild == NULL))
WPL_PreOrder(T->lchild, level + 1);
else
WPL_PreOrder(T->rchild, level + 1);
}
}
// main 函式中呼叫:
WPL_PreOrder(Tree, 0);
6 將表示式樹轉化為等價的中綴表示式
請設計一個演算法,將給定的表示式樹,轉換成等價的中綴表示式並輸出。
二叉樹結點定義如下:
typedef struct node{
char data[10];
struct node *left, * right;
} BTree;
演算法的核心思想是中序遍歷 + 計算層數。可以先將中序遍歷的表示式先寫出來,再與加了括號的表示式對比一下,看看哪個地方加了括號。遍歷左子樹前加上左括號,遍歷完右子樹後加上右括號,根結點(表示式最外層)和葉結點(運算元)不需要加括號。程式碼如下:
void InOrder (BTree *T, int level){
if (T != NULL){
if ((T->left == NULL) && (T->right == NULL)) // 葉結點
輸出 T->data; // 輸出運算元
else{
if (level > 1) // 若有子表示式則加 1 層括號
輸出 "(";
InOrder(T->left, level + 1);
輸出 T->data; // 輸出操作符
InOrder(T->right, level + 1);
if (level > 1) // 若有子表示式則加 1 層括號
輸出 ")";
}
}
}
// main 函式中呼叫:
InOrder(Tree, 0);