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

    AVL(Adelson-Velskii and Landis)树是带有平衡条件的二叉查找树。其每个结点的左子树和右子树的高度最多差1.

    在高度为h的AVL树中,最少结点数S(h)=S(h1)+S(h2)+1。对于h=0,S(h)=1;h=1,S(h)=2

    AVL的树的结点声明

    struct AvlNode
    {
        int element;
        AvlNode *left;
        AvlNode *right;
        int height;
    
        AvlNode(const int& theElement, AvlNode *lt, AvlNode* rt, int h = 0):element(theElement), left(lt), right(rt), height(h)
        {}
    };

    计算AVL结点高度的函数


    int height( AvlNode *t )
    {
        return (t==NULL)?-1:t->height;
    }

    执行单旋转的函数

    单旋转

    /**
    * 将左边的树变成右边的树,并返回指向新根的指针.
    */
    void* rotateWithLeftChild( AvlNode * &k2 )
    {//给指针加引用,则可对指针的值做修改
        AvlNode *k1 = k2->left;
        k2->left = k1->right;
        k1->right = k2;
        k2->height = max( height(k2->left), height(k2->right) )+1;
        k1->height = max( height(k1->left), height(k1->right) )+1;
        return k1;
    }

    rotateWithRightChild与之对称。

    执行双旋转的函数

    双旋转

    void doubleWithLeftChild( AvlNode * & k3)
    {
        rotateWithRightChild( k3->left);
        rotateWithLeftChild(k3);
    }

    doubleWithRightChild与之对应。

    AVL树的插入操作

    /**
     * Interal method to insert into a subtree.
     * x is the item to insert.
     * t is the node that roots the subtree.
     * Set the new root of the subtree.
    */
    void insert( const int & x, AvlNode * & t )
    {
        if (t == NULL)
            t == new AvlNode( x, NULL, NULL );
        else if (x < t->element)
        {
            insert( x, t->left );
            if ( height( t->left ) - height( t->right) == 2 )
            {
                if ( x < t->left->element )
                    rotateWithLeftChild( t );//在左孩子的左子树中插入
                else
                    doubleWithLeftChild( t );//在左孩子的右子树中插入
            }
        }
        else if (x > t->element)
        {
            insert( x, t->right );
            if ( height( t->right ) - height( t->left) ) == 2 )
            {
                if (t->right->element < x)
                    rotateWithRightChild( t );//在右孩子的右子树中插入
                else
                    doubleWithRightChild( t );//在右孩子的左子树中插入
            }
        }
        else
        ;
        t->height = max( height( t->left ), height( t->right) ) + 1;
    }

    附录

    在二叉树中插入元素共分为四类:
    * 在左儿子的左子树中插入;
    * 在左儿子的右子树中插入;
    * 在右儿子的左子树中插入;
    * 在右儿子的右子树中插入;
    例如:
    1.在左儿子的左子树中插入
    左左

    2.在右儿子的右子树中插入
    右右

    3.在左儿子的右子树中插入
    左右

    4.在右儿子的左子树中插入
    右左

  • 相关阅读:
    MongoDB —— 第三篇 高级操作
    MongoDB —— 第七篇 运维技术
    MongoDB —— 第八篇 驱动实践
    EditPlus 使用技巧集萃(转)
    面试经验网上资源汇总
    设计模式网上资料整合理解——创建型模式(一)
    C#编写扩展存储过程
    利用VS调试脚本
    用DevExpress.XtraReports实现复杂报表套打的一些经验
    无废话.NET帮助文件生成——Sandcastle+SHFB
  • 原文地址:https://www.cnblogs.com/happygirl-zjj/p/4574619.html
Copyright © 2011-2022 走看看