avl树

Posted wzl19981116

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了avl树相关的知识,希望对你有一定的参考价值。

自动平衡二叉树,可以保证每次增加,输出,查询只用log(N)的时间复杂度

模板

struct node
{
    int lc,rc,h,v;
}tree[N];
int pos=0,x1,x2,root;
int right_rotate(int r)//zig右旋
{
    int t = tree[r].lc;
    tree[r].lc = tree[t].rc;
    tree[t].rc = r;
    tree[r].h = max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;
    tree[t].h = max(tree[tree[t].lc].h,tree[tree[t].rc].h)+1;
    return t;
}
int left_rotate(int r)//zag左旋
{
    int t = tree[r].rc;
    tree[r].rc = tree[t].lc;
    tree[t].lc = r;
    tree[r].h = max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;
    tree[t].h = max(tree[tree[t].lc].h,tree[tree[t].rc].h)+1;
    return t;
}
int right_left_rotate(int r)//zigzag双旋
{
    tree[r].rc = right_rotate(tree[r].rc);
    return left_rotate(r);
}
int left_right_rotate(int r)//zagzig双旋
{
    tree[r].lc = left_rotate(tree[r].lc);
    return right_rotate(r);
}
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 = right_rotate(r);//左子树的左儿子,对应第一种情况
        else if(tree[tree[t].rc].h == tree[tree[r].rc].h+1) r = left_right_rotate(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 = left_rotate(r);//右子树的右儿子,对应第四种情况
        else if(tree[tree[t].lc].h == tree[tree[r].lc].h+1) r = right_left_rotate(r);
    }
    tree[r].h = max(tree[tree[r].lc].h,tree[tree[r].rc].h)+1;//高度更新
}

int insert(int r,int x)//插入x
{
    if(r == 0)//找到一个空的节点,赋值
    {
        tree[++pos].h = 1;//高度初始化
        tree[pos].v = x;
        return pos;
    }
    if(x < tree[r].v) tree[r].lc = insert(tree[r].lc,x);//插入的数小于根节点,因此在它的左子树插入
    else if(x > tree[r].v) tree[r].rc = insert(tree[r].rc,x);
    maintain(r);//维持节点r的平衡
    return r;//返回新的根节点
}
int kth(int r,int k)//查找第k大,tree[r].tot保存了值等于tree[r].v的个数
{
    if(k >= tree[tree[r].rc].sz+1&&k <= tree[tree[r].rc].sz+tree[r].tot) return tree[r].v;//找到
    if(k < tree[tree[r].rc].sz+1) return kth(tree[r].rc,k);//在右子树中
    else return kth(tree[r].lc,k-tree[tree[r].rc].sz-tree[r].tot);//在左子树中,此种情况下,K值发生变化,因为要求得的那个点它在左子树中的排名发生了变化
}

int delt(int &r,int x)//删除x
{
    int tx;
    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)
        {
            tx = tree[r].v;
            r = tree[r].lc+tree[r].rc;
            return tx;
        }
        else tree[r].v = delt(tree[r].lc,x);//用左子树的最大值来替换
    }
    else
    {
        if(x < tree[r].v) tx = delt(tree[r].lc,x);
        else tx = delt(tree[r].rc,x);
    }
    maintain(r);//调整根节点
    return tx;//返回最大值
}
void find(int x,int r)
{
    int v=tree[r].v;
    if(x==v) 
    {
        prf(x);
        return;
    }
    pf("%d ",v );
    if(x<v)
        find(x,tree[r].lc);
    else
        find(x,tree[r].rc);
}
void prem(int x,int r)//x的前驱
{
    if(r == 0) return;
    if(tree[r].v < x)
    {
        x1 = tree[r].v;
        prem(x,tree[r].rc);
    }
    else prem(x,tree[r].lc);
}
void nexm(int x,int r)//后继
{
    if(r == 0) return;
    if(tree[r].v > x)
    {
        x2 = tree[r].v;
        nexm(x,tree[r].lc);
    }
    else nexm(x,tree[r].rc);
}

以上是关于avl树的主要内容,如果未能解决你的问题,请参考以下文章

C++AVL树的实现--详细解析旋转细节

[算法] 数据结构之AVL树

树:AVL树

徒手写的AVL竟然比STL中的红黑树效率更高?✨

AVL树

C++ AVL树