AVL树笔记(二):maintain,delete

原创 2015年11月17日 22:50:38

先是maintain操作,它可以维护AVLTree的平衡。
有了maintain,AVLTree的insert和delete就可以不马上维护平衡,而是操作完再维护平衡了。

void maintain(int &r)
{
    if(tree[tree[r].lc].h==tree[tree[r].rc].h+2)
    {
        int t=tree[r].lc;
        if(tree[tree[t].lc].h==tree[tree[r].rc].h+1)r=zig(r);
        else if(tree[tree[t].rc].h==tree[tree[r].rc].h+1)r=zagzig(r);
    }
    else if(tree[tree[r].rc].h==tree[tree[r].lc].h+2)
    {
        int t=tree[r].rc;
        if(tree[tree[t].rc].h==tree[tree[r].lc].h+1)r=zag(r);
        else if(tree[tree[t].lc].h==tree[tree[r].lc].h+1)r=zigzag(r);
    }
    tree[r].h=max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;
}

仔细看会发现和昨天的insert的维护平衡比较相似。
就是这次不能凭借tree[r].v和插入值x来比较x在左子树还是右子树了,要根据h来判断。
然后insert就是二叉查找树的insert了:

int insert(int r,int x)
{
    if(r==0)
    {
        tree[++cnt].v=x;
        tree[cnt].h=1;
        return cnt;
    }
    if(tree[r].v>x)tree[r].lc=insert(tree[r].lc,x);
    else if(tree[r].v<x)tree[r].rc=insert(tree[r].rc,x);
    maintain(r);
    return r;
}

接下来是delete操作:
首先我们要find,find到了再delete。
要delete的点如果是叶子,那么直接删掉,如果只有一个儿子,那么把这个点删掉,把它的父亲直接连到它的儿子。
如果左右儿子都有,就比较麻烦了。
可以找到它的前驱,把这个点的值修改成前驱的值,最后删掉前驱。
可以证明的是,前驱一定不存在有左右2个儿子都有的状况。
可行是因为删掉这个点,前驱就会上来。还不如直接把这个点改成前驱,再删掉以前那个前驱。
实际实现可以参考find。
find到了,如果是前2种状况,那么删掉,如果是第三种,那么递归删去当前点的前驱。
删完记得维护h值。

int del(int &r,int x)
{
    int tv;
    if(x==tree[r].v||(x<tree[r].v&&tree[r].lc==0)||(x>tree[r].v&&tree[r].rc==0))
    {
        if(tree[r].lc==0||tree[r].rc==0)
        {
            tv=tree[r].v;
            r=tree[r].lc+tree[r].rc;
            return tv;
        }
        else tree[r].v=del(tree[r].lc,x);
    }
    else
    {
        if(tree[r].v>x)tv=del(tree[r].lc,x);
        else tv=del(tree[r].rc,x);
    }
    maintain(r);
    return tv;
}

不要直接调用求前驱的函数,貌似时间复杂度会变大= =

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

AVL树读书笔记

最近开始了自己高级数据结构之旅,在这次旅行中,我将持续把一些高级的数据结构从理论到编码都过一遍,同时通过博客形式分享出来,希望大家指出不足之处!      二叉排序树是一种动态排序的数据结构,支持插入...

平衡二叉树AVL的笔记

二叉树 左子树都小于根节点,右子树都大于根节点。可以动态维护这棵树(因为是树结构,可以有限步完成插入),所以是动态查找算法。时间复杂度为O(logn)在46.5%的情况下,需要把二叉树平衡化成“...

[学习笔记]AVL平衡二叉树

AVL平衡二叉树的实现
  • cyxvc
  • cyxvc
  • 2015年08月26日 14:00
  • 219

avl树-《算法导论》学习笔记十三

(引用算法导论)AVL树是一种高度平衡的二叉搜索树:对每一个结点x,y的左子树与右子树的高度至多为1。AVL树相比二叉搜索树,每个结点维护一个额外的属性:结点的高度。AVL树实现了几个操作: 树结点创...

《数据结构与算法分析c++描述》读书笔记三——AVL树

AVL树:对于每一个节点都要满足其左右子树的高度差不得大于1的二叉树(平衡条件)。当经过插入操作或者删除操作后破坏了树的平衡性时,要经过调整恢复平衡性后才认为一次插入或者删除操作完成。这样的调整总是可...

算法学习笔记(七) 平衡二叉树 AVL树

AVL树是最先发明的自平衡二叉查找树, 其增删查时间复杂度都是 O(logn), 是一种相当高效的数据结构。当面对需要频繁查找又经常增删这种情景时,AVL树就非常的适用。 对比红黑树: 红黑树对于数值...

AVL树(二叉平衡树)笔记

先上代码 后续补充-- #include #include#include typedef struct TreeNode* T; struct TreeNode{ int bf; int he...

AVL树初学笔记

AVL树是带有平衡条件的binary_search_tree,要求每个节点的左子树和右子树的高度相差不超过1 插入一个节点可能破会avl的平衡性,所以我们要在插入后对不满足条件的部分进行修正...

【C++研发面试笔记】10. 基本数据结构-平衡二叉搜索树AVL

【C++研发面试笔记】10. 基本数据结构-平衡二叉搜索树AVL10.1 AVL的定义定义:平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1; (2)左右子树...
  • tostq
  • tostq
  • 2016年10月02日 21:52
  • 723

[算法学习笔记] AVL树----带有平衡条件的二叉搜索树

图片及部分内容来自博客http://www.cnblogs.com/skywang12345/p/3576969.html 这个博客写的很用心,大家可以看看这个 二叉搜索树关于二叉搜索树我之前的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AVL树笔记(二):maintain,delete
举报原因:
原因补充:

(最多只允许输入30个字)