zoukankan      html  css  js  c++  java
  • 平衡树

     

    treap:
    (1)树+堆。具体是随机某个节点的值,然后维护这个值满足堆的性质。
    (2)代码实现

    sbt:
    (1)陈大神的节点大小平衡树,其实就是根据四种情况进行调整,而这四种情况也是其他bst会使用的调整方式。中心思想就是当节点信息变时,用maintain调整
    (2)代码实现

    procedure maintain(var t:longint);
    begin
    if s[left[left[t]]]>s[right[t]] then begin //左左>右的情况:先右旋,当前根右节点变了,需要调整,然后根变了,需要调整。
    rightrotate(t);
    maintain(right[t]);
    maintain(t);
    exit;
    end;
    if s[right[left[t]]]>s[right[t]] then begin //左右>右的情况:先左旋左儿子,使左右变成左儿子,再左旋,让左儿子变成根,至此,当前根的左儿子要调整,当前根的右儿子也要调整,当前根也要调整
    leftrotate(left[t]);
    rightrotate(t);
    maintain(left[t]);
    maintain(right[t]);
    maintain(t);
    exit;
    end;
    if s[right[right[t]]]>s[left[t]] then begin
    leftrotate(t);
    maintain(left[t]);
    maintain(t);
    exit;
    end;
    if s[left[right[t]]]>s[left[t]] then begin
    rightrotate(right[t]);
    leftrotate(t);
    maintain(left[t]);
    maintain(right[t]);
    maintain(t);
    end;
    end;
    View Code

    splay:

    (1)通过不断翻转来实现平衡

    (2)代码实现

     

    平衡树有一些公共的操作

    find:查找是否有只为v的节点

    function find(var t,v:longint):boolean;inline;
    begin
       if t=0 then
          exit(false);
       if v<key[t] then
          find:=find(left[t],v)
       else
          find:=(key[t]=v)or find(right[t],v);
    end;
    View Code

    rank:查找值为v的点的排名

    具体做法:

    1)如果当前是空节点,那就退出1

    2)不是的话,如果v小于等于当前节点的值,那么就往左儿子找,如果大于当前节点,说明v值得排名至少有s[left[t]]+1,再查找右儿子。

    function rank(var t,v:longint):longint;inline;
    begin
       if t=0 then
          exit(1);
       if v<=key[t] then
          rank:=rank(left[t],v)
       else
          rank:=s[left[t]]+1+rank(right[t],v);
    end;
    View Code

    select:查找排名为k的点的值

    具体做法:

    1)如果当前这个点的左儿子+1=排名k,那么就是这个点啦

    2)如果不是的话,如果k小于等于左儿子的节点数,那么就找左儿子,如果不是,那么找右儿子中排名为k-1-s[left[t]]的点

    pred:查找值小于(不能等于)v的最大值

    function pred(var t,v:longint):longint;inline;
    begin
       if t=0 then
          exit(v);
       if v<=key[t] then
          pred:=pred(left[t],v)
       else begin
          pred:=pred(right[t],v);
          if pred=v then
             pred:=key[t];
       end;
    end;
    View Code

    (把exit(v)变成exit(maxlongint)也可以?总觉得我以前就是用maxlongint)

    succ:查找值大于(不能等于)v的最小值

    function succ(var t,v:longint):longint;inline;
    begin
       if t=0 then
          exit(v);
       if key[t]<=v then
          succ:=succ(right[t],v)
       else begin
          succ:=succ(left[t],v);
          if succ=v then
             succ:=key[t];
       end;
    end;
    View Code

     

     

     

    bzoj1588 [HNOI2002]营业额统计 (treap)

    bzoj1251: 序列终结者 (splay)

    bzoj1208: [HNOI2004]宠物收养所 (sbt)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3224

    http://www.lydsy.com/JudgeOnline/problem.php?id=3223

    http://www.lydsy.com/JudgeOnline/problem.php?id=3196

  • 相关阅读:
    在酷热的就业天气寻找几丝凉意
    《Orange ’ s :一个操作系统的实现 》作者自序
    Windows的设备驱动框架
    Windows的设备驱动框架中的上层与下层模块
    如何搭建自己的开发环境
    数据库设计指南(二)设计表和字段
    软件敏捷架构师
    Struts到JSF/Tapestry
    敏捷开发
    barcode制作条形码及破解
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4290931.html
Copyright © 2011-2022 走看看