2.3 - Binary Tree Traversal

介紹Binary Tree追蹤法則

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左方為 TLT_{L} ,節點數 nLn_{L} ;右方為 TRT_{R} 節點數 nRn_{R}

再到pre-order中的第二個點取出 nLn_{L} 個節點,為 TLT_{L}^{*} ;接續取出 nRn_{R} 個節點,為 TRT_{R}^{*}

TLT_{L}^{*}TRT_{R}^{*} 為左右子樹的pre-order,且nLn_{L}nRn_{R} n1≤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;
        }
    }
}

Last updated