二叉树

1. 概念

  二叉树是有限个结点的集合,这个集合或者是空集,或者由一个根节点和两棵不相交的二叉树组成,其中一棵叫做根的左子树,另一棵叫做根的右子树。

  满二叉树是高为k且有2^k - 1个结点的二叉树。

  完全二叉树是具有下述性质的二叉树:

   a. 所有叶结点都在k或者k-1层
   b. k-1层的所有叶结点都在非终结符结点的右边
   c. 只有k-1层最右非终结结点可能有一个叶子结点

2. 性质

  • 性质1:在二叉树中第i层的结点数量最多为2^(i-1)
  • 性质2:高度为k的二叉树其结点数最多为2^k - 1
  • 性质3:如下图

image_1bd728cr61gup1vdjs9p10ialnh9.png-89.1kB

3. 基本操作

操作 | 解释

  • | -
    Empty(BT) | 建立一棵空的二叉树
    IsEmpty(BT) | 为空则返回TRUE
    CreateBT(v,LT,RT) | 建立新树,根值为v,另外为左右子树
    Lchild(BT) | 返回左儿子
    Rchild(BT) | 返回右儿子
    Data(BT) | 返回根节点数据预的值

4. 遍历方式

假设图如下:

image_1bd72a5vm1a1817n81pfir111ergm.png-19.5kB

  • 先根遍历:A B D H I E J C F G

  • 中根遍历:H D I B J E A F C G

  • 后根遍历:H I D J E B F G C A

  • 给出先根遍历代码:

    void PreOrder(BTREE BT)
    {
        if(!IsEmpty(BT)) {
            visit(Data(BT));  //中根遍历放中间,后根遍历同理
            PreOrder(Lchild(BT));
            PreOrder(Rchild(BT));
        }
    }

5. 二叉树的实现

5.1 左右链表示

  • 示意图:

image_1bd7368jtph71lkepsc9fu5e13.png-19.1kB

  • 代码实现:
    struct node {
        node *lchild;
        datatype data;
        node *rchild;
    };
    
    typedef node * BTREE;
    
    BTREE CreateBT(datatype v, BTREE ltree, BTREE rtree)
    {
        BTREE root;
        root = new node;
        root->data = v;
        root->lchild = ltree;
        root->rchild = rchild;
        return root;
    }

5.2 游标表示

  • 示意图:

image_1bd73e8ia2c51cqgdbb1bdsov71g.png-13.4kB

  • 代码实现:
    struct {
        int lchild;
        int rchild;
    } cellspace[maxnodes];
    
    /*
        cellspace[i].lchild是结点i的左儿子,
        如果为-1,表示没有相应的儿子,
        图中可以看出
    */

5.3 线索二叉树

  • 概念:在左右链的表示法中,具有n个结点的树需要2n个指针,必然会造成浪费,故利用浪费的指针指向有用的地方。

    • 当某个结点的lchild为空时,则令其指向该结点的中根遍历的前导结点
    • 若rchild为空,则指向中根遍历的后续结点
  • 示意图

image_1bd73morh1hb0spe13jv5221psf1t.png-43.4kB

  • 代码实现:
    struct node{
        node *lchild;
        node *rchild;
        boolean ltag;
        boolean rtag;
        infotype info;
    };    
  • 规则
    • 若P的左子树为空,则令P->ltag=FALSE,且P->lchild=$P
    • 若P的左子树不为空,则令P->ltag=TRUE,且P->lchild=左子树的根
    • 若P的右子树为空,则令P->rtag=FALSE,且P->rchild=P$
    • 若P的右子树不为空,则令P->rtag=TRUE,且P->rchild=右子树的根

$P表示P在中根遍历序列中的前导结点

  • 特殊情况

  线索二叉树总是由低的位置指向高的位置。在中序遍历第一个结点H和最后一个结点G,需要建立一个空结点HEAD,让它们的指针指向其,如下:

    HEAD->lchild = T; //T是指向根结点的指针
    HEAD->rchild = HEAD;
    HEAD->ltag = TRUE;
    HEAD->rtag = TRUE;
    
    //空二叉树则为:
    HEAD->lchild = HEAD;
    HEAD->ltag = FALSE;
    HEAD->rchild = HEAD;
    HEAD->rtag = TRUE;
    

线索二叉树在对于“给定P,求$P或者P$时特别容易”

5.4 完全二叉树的数组表示法

  • 示意图

image_1bd8879cnnfokdg16f81a1818flm.png-15.4kB

  • 规则
    • 若i != 1,则其父亲结点是⌊i/2⌋
    • 若i == 1,则i是根结点
    • 若2i <= n,则左儿子是2i,若2i > n,则i无左儿子
    • 若2i+1 <= n,则右儿子是2i+1,若2i+1 > n,则无右儿子

部分资料来自《数据结构与算法--张岩》

posted @ 2017-04-09 13:22  va_chester  阅读(332)  评论(0编辑  收藏  举报