zoukankan      html  css  js  c++  java
  • 二叉树

    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,则无右儿子

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

  • 相关阅读:
    IntelliJ IDEA 使用svn教程
    尾递归
    斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)
    斐波拉契数列的计算方法
    C#实现多线程的方式:Task——任务
    LINQ查询表达式详解(2)——查询表达式的转换
    LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询
    完成异步委托的三种方式
    C#实现多线程的方式:使用Parallel类
    C#实现多线程的方法:线程(Thread类)和线程池(ThreadPool)
  • 原文地址:https://www.cnblogs.com/vachester/p/6684444.html
Copyright © 2011-2022 走看看