• 【模板】左偏树


    一、左偏树的性质

    左偏树,又称可并堆,所以他有堆的性质。

    定义几个量:(val)表示该节点的值,(fa)表示该节点的父亲,(ch[2])表示该节点的两个儿子(因为他是二叉树),(dis)表示这个节点到离他最近的叶子节点的距离。

    性质一:该节点的val不大于该节点左右儿子的val

    证明:堆。

    性质二:该节点左儿子的dis不小于该节点右儿子的dis

    证明:左偏树的定义。为了更快的进行合并、查询、删除(快速提取最小值)。

    性质三:该节点的dis等于该节点右儿子的dis。

    证明:构造的。

    性质四:一棵n个节点的左偏树的节点的距离k最多为(log(n+1)-1)

    证明:因为左偏树是一棵二叉树,当他节点最少的时候他是一棵完全二叉树,所以(n>=2^(k+1)-1),那么(k<=log(n+1)-1)。(这个结论是用来证明左偏树的时间复杂度的)

    二、左偏树的主要操作

    左偏树的主要实现就是他的merge,我们删除,插入一个节点就是利用左偏树的merge函数进行操作的。

    merge函数的实现方法:

    首先,我们建出来的左偏树是一定要符合以上四个性质的,所以我们的merge就是为了在合并后,左偏树仍有这些性质。

    1.我们要保证性质一

    所以:

    if(val[x]>val[y]||(val[x]==val[y]&&x>y))//性质一
    {
    	swap(x,y);
    }
    

    2.我们要开始合并,我们将以节点y形成的左偏树和节点x的右子树合并,在让合并后所形成的的左偏树满足性质。

    ch[x][1]=merge(ch[x][1],y);//合并右子树和y
    

    3.合并后的左偏树要满足性质三

    dis[x]=dis[ch[x][1]]+1;//性质三
    

    4.我们要更新节点的fa

    fa[x]=fa[ch[x][0]]=fa[ch[x][1]]=x;//更新fa
    

    5.为了操作4,我们要return 根节点

    return x;
    

    综上,merge函数就是:

    int merge(int x,int y)
    {
    	if(!x||!y)
    	{
    		return x+y;
    	}
    	if(val[x]>val[y]||(val[x]==val[y]&&x>y))//性质一
    	{
    		swap(x,y);
    	}
    	ch[x][1]=merge(ch[x][1],y);//合并右子树和y
    	if(dis[ch[x][0]]<dis[ch[x][1]])//性质二
    	{
    		swap(ch[x][0],ch[x][1]);
    	}
    	fa[x]=fa[ch[x][0]]=fa[ch[x][1]]=x;//更新fa
    	dis[x]=dis[ch[x][1]]+1;//性质三
    	return x;
    }
    

    三、基于merge函数的操作

    删除某一节点(pop)

    我们只要合并这个节点的左右儿子即可。

    void pop(int x)
    {
    	val[x]=-1;
    	fa[ch[x][0]]=ch[x][0];
    	fa[ch[x][1]]=ch[x][1];
    	fa[x]=merge(ch[x][0],ch[x][1]);
    }
    

    求某一节点所在堆得最小值,并删除此节点

    xx=getfa(x);
    printf("%d
    ",val[xx]);
    pop(xx);
    

    另:

    有关getfa:

    一定要路径压缩,不然原来(O(logn))的查询,就会被一条链卡成(O(n))

    四、例题:

    1.罗马游戏
    2.Joint Stacks

  • 相关阅读:
    分布式架构高可用架构篇_activemq高可用集群(zookeeper+leveldb)安装、配置、高可用测试
    @interface [SpringMVC+redis]自定义aop注解实现控制器访问次数限制
    ActiveMQ安装与持久化消息
    activemq 5.13.2 jdbc 数据库持久化 异常 找不到驱动程序
    java通过Comparable接口实现字符串比较大小排序的简单实例
    微信小程序--火车票查询
    【调试】如何使用javascript的debugger命令进行调试(重要)
    【调试】js调试console.log使用总结图解(重要)
    ajax提交表单
    一个项目的404错误处理页面
  • 原文地址:https://www.cnblogs.com/2017gdgzoi44/p/11377317.html
Copyright © 2020-2023  润新知