> For the complete documentation index, see [llms.txt](https://garychang.gitbook.io/data-structure/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://garychang.gitbook.io/data-structure/lecture2-tree-and-binary-tree/lecture2.3-binary-tree-traversal.md).

# 2.3 - Binary Tree Traversal

### 1. 介紹

```
         Root
       /      \
Left Child   Right Child
```

* Left child必須在Right child之前拜訪

1. **Pre-order（前序）**：root → left child → right child
2. **In-order（中序）**：left child → root → right child
3. **Post-order（後序）**：left child → right child → root
4. **level-order**：依照level由上而下，由左而右

### 2. 應用

#### 2.1 求Binary Tree的前中後序

```
       A
     /   \
    B     C
   / \   / \
  D  E  F   G
```

1. pre-order: A-B-D-E-C-F-G
2. in-order: D-B-E-A-F-C-G
3. post-order: D-E-B-F-G-C-A
4. level-order: A-B-C-D-E-F-G

#### 2.2 給予Binary Tree的(前序、中序)或是(後序、中序)可決定唯一的Binary Tree

(complete/full binary tree的前、中、後序皆可決定唯一binary tree)

證明:

1. 當節點數=0時，binary tree為空。pre-order=in-order=0，此binary tree為空。
2. 假設節點數=n-1時此定理成立。
3. 當節點數=n時，從pre-order中找出root為R，再到in-order中找到R的位置。

令R左方為 $$T\_{L}$$ ，節點數 $$n\_{L}$$ ；右方為 $$T\_{R}$$ 節點數 $$n\_{R}$$&#x20;

再到pre-order中的第二個點取出 $$n\_{L}$$ 個節點，為 $$T\_{L}^{*}$$ ；接續取出 $$n\_{R}$$ 個節點，為 $$T\_{R}^{*}$$&#x20;

&#x20;$$T\_{L}^{*}$$和 $$T\_{R}^{*}$$ 為左右子樹的pre-order，且$$n\_{L}$$ 、 $$n\_{R}$$ $$≤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的應用

1. copy()：複製binary tree。
2. equal()：比較binary tree。
3. count()：求binary tree節點總數。
4. height()：求binary tree高度。
5. 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表示運算式

1. leaf -> 運算元
2. non-leaf -> 運算子
3. 運算子優先權越高，level越大

```
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;
        }
    }
}
```
