1. 介紹
Root
/ \
Left Child Right Child
Left child必須在Right child之前拜訪
Pre-order(前序):root → left child → right child
In-order(中序):left child → root → right child
Post-order(後序):left child → right child → root
level-order:依照level由上而下,由左而右
2. 應用
2.1 求Binary Tree的前中後序
A
/ \
B C
/ \ / \
D E F G
post-order: D-E-B-F-G-C-A
level-order: A-B-C-D-E-F-G
2.2 給予Binary Tree的(前序、中序)或是(後序、中序)可決定唯一的Binary Tree
(complete/full binary tree的前、中、後序皆可決定唯一binary tree)
證明:
當節點數=0時,binary tree為空。pre-order=in-order=0,此binary tree為空。
當節點數=n時,從pre-order中找出root為R,再到in-order中找到R的位置。
令R左方為 TL ,節點數 nL ;右方為 TR 節點數 nR
再到pre-order中的第二個點取出 nL 個節點,為 TL∗ ;接續取出 nR 個節點,為 TR∗
TL∗和 TR∗ 為左右子樹的pre-order,且nL 、 nR ≤n−1 滿足第二點假設。根據數學歸納法,此定理成立。
2.3 Recursive Traversal Algorithm
void preorder(bt_tree *bt){
if (bt != NULL){
printf("%d", bt->Data);
preorder(bt->lchild);
preorder(bt->rchild);
}
}
void inorder(bt_tree *bt){
if (bt != NULL){
preorder(bt->lchild);
printf("%d", bt->Data);
preorder(bt->rchild);
}
}
2.4 Recursive Traversal Algorithm的應用
count():求binary tree節點總數。
swap():將binary tree的children對調。
bt_tree *copy(bt_tree *bt_ori){
static bt_tree *bt_new;
if (bt_ori == NULL){
bt_new = NULL;
}
else{
bt_new->Data = bt_ori->Data;
bt_new->lchild = copy(bt_ori->lchild);
bt_new->rchild = copy(bt_ori->rchild);
}
return bt_new;
}
bool equal(bt_tree *bt1, bt_tree *bt2){
if (bt1 == NULL && bt2 == NULL) return True;
else{
if (bt1->Data == bt2->Data)
if (equal(bt1->lchild, bt2->lchild))
return equal(bt1->rchild, bt2->rchild);
return False;
}
}
int count(bt_tree *bt){
int nl, nr;
if (bt == NULL) return 0;
else{
nl = count(bt->lchild);
nr = count(bt->rchild);
return nl+nr+1;
}
}
int height(bt_tree *bt){
int hl, hr;
if (bt == NULL) return 0;
else{
hl = count(bt->lchild);
hr = count(bt->rchild);
return max(hl, hr)+1;
}
}
void swap(bt_tree *bt){
bt_tree *temp;
if (bt != NULL){
swap(bt->lchild);
swap(bt->rchild);
temp = bt->lchild;
bt->lchild = bt->rchild;
bt->rchild = temp;
}
}
2.5 以binary tree表示運算式
a+b*c-d
-
/ \
+ d
/ \
a *
/ \
b c
int eval(bt_tree* bt){
if (bt != NULL){
eval(bt->lchild);
eval(bt->rchild);
switch(bt->Data){
case '+': return (bt->lchild)->Data+(bt->rchild)->Data;
case '-': return (bt->lchild)->Data-(bt->rchild)->Data;
case '*': return (bt->lchild)->Data*(bt->rchild)->Data;
case '/': return (bt->lchild)->Data/(bt->rchild)->Data;
default: return bt->Data;
}
}
}