• 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);
    }
    
    
  • 相关阅读:
    centos8 防火墙配置增加端口
    linux上搭建maven私服(下)
    linux上搭建maven私服(中)
    项目成本管理中的PV、EV与AC的区别-实例解释
    配置IKE SA的生存周期(华为)
    IKE SA和IPSec SA的区别
    IPsecVPN协商过程-主模式
    Fortigate防火墙常用命令
    飞塔防火墙清除系统密码
    fatal: unable to access ‘https://github xxxxxxxxx的解决方法
  • 原文地址:https://www.cnblogs.com/wzl19981116/p/9940936.html
Copyright © 2020-2023  润新知