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树插入删除算法详解(有图) -- C++语言实现

一:AVL树介绍 AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树。 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。在本文中用分别用-1,0...
  • FreeeLinux
  • FreeeLinux
  • 2016年08月14日 21:42
  • 2836

AVL树的插入与删除(均为递归实现)

AVL树是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是O(lonN).一颗AVL树是其每个节点的左子树和右子树的高度最多差一的二叉查找树. 主要介绍插入算法和删除算法...
  • ytang007
  • ytang007
  • 2016年09月21日 21:22
  • 1029

算法--AVL树的删除

AVL 树删除 定义 AVL树是一棵二叉查找树,平衡因子为-1,1,0.若平衡因子为2就必须进行平衡化。平衡化的过程就是左旋或者右旋,分LL,LR,RR,RL4种情况。 性能: 高度为:log...
  • tang_jin2015
  • tang_jin2015
  • 2013年02月27日 03:42
  • 1058

AVL Tree 平衡二叉树基本插入删除节点功能的实现

简述: 实现AVL 树,主要是两个功能 : 插入某节点和删除某节点 AVL Tree的定义, 1. 是一棵二叉搜索树(故而每个节点是惟一的, 如果出现重复数字会破坏平衡树的算法) 2....
  • anialy
  • anialy
  • 2012年09月18日 20:40
  • 10996

平衡二叉树(AVL)的插入和删除详解(上)

AVL树维基百科:http://zh.wikipedia.org/wiki/AVL树 在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也...
  • sysu_arui
  • sysu_arui
  • 2012年08月22日 19:02
  • 15301

AVL树原理通俗解释与例子

AVL(Adelson-Velskii and Landis)树是带有平衡条件(balance condition)的二叉查找树。 这个平衡条件必须容易保持,而且必须保证树的深度是O(logN)。 A...
  • songzige
  • songzige
  • 2016年04月21日 16:37
  • 1006

AVL树的初步生成与插入操作

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树...
  • u011446963
  • u011446963
  • 2015年07月02日 17:05
  • 1383

AVL树(模板题)—— POJ 3481 Double Queue

AVL树(模板题)—— POJ 3481 Double Queue
  • u013351484
  • u013351484
  • 2015年08月01日 19:18
  • 827

算法导论第十三章习题13-3——AVL树(高度平衡树)C++代码详细实现

AVL树是一种高度平衡树,对于每一个节点,其左子树的高度与右子树的高度相差之多为1。 AVL树是比红黑树更加平衡的树(红黑树中左右子树高度之比小于2)。 AVL树除了平衡性较好外,与普通的二叉查找...
  • liuzhanchen1987
  • liuzhanchen1987
  • 2012年08月03日 16:06
  • 4041

AVL树的旋转图解和简单实现

AVL树是带有平衡条件的查找二叉树。这个平衡条件要容易保持,而且他要保证树的深度为O(logN)原文地址:http://blog.csdn.net/qq_25806863/article/detail...
  • qq_25806863
  • qq_25806863
  • 2017年07月07日 18:03
  • 489
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AVL树笔记(二):maintain,delete
举报原因:
原因补充:

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