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

    前言

    学了 FHQ Treap ,据说那玩意能代替 Splay,所以就懒得学Splay 了 = =,直到老吕给我们讲了 Splay,发现这玩意确实也挺香滴 /se

    这儿主要参考 attack 学长的博客,所以这就不再详细写了(主要是懒

    简介

    Splay 也是平衡树的一种,所以它还是基于二叉搜索树的

    主要思想:对于查找频率较高的节点,使其处于离根节点相对较近的节点

    Splay 的特色操作:rotate 和 Splay

    操作

    具体操作和 Treap 类似,但是这不是父亲向下挪,而是儿子向上挪(效果其实一个样),相比于 Treap,Splay 要维护每个点父亲的信息

    rotate

    使得一个点挪到它的父亲节点

    • 当 X 是 Y 的左孩子
          R                R
                           
            Y                X
           /      ->       /  
          X               A    Y
         /                   / 
        A   B                B   C
    
    • 当 X 是 Y 的右孩子
          R                      R
                                 
            Y                      X
          /           ->         / 
         A    X                 Y    C
             /                / 
            B    C            A   B
    

    发现:如果让 X 成为 Y 的父亲,只会影响三个点关系,B 与 X, X 与Y, X 和 R

    规律:

    B 成为 Y 的哪个儿子与 X 是 Y 的哪个儿子是一样的

    Y 成为 X 的哪个儿子与 X 是 Y 的哪个儿子相反

    X 成为 R 的哪个儿子与 Y 是 R 的哪个儿子相同

    那么只需要得出每个点是它父亲的什么儿子就好了

    Splay

    把 x 节点挪到 to 节点

    • 如果 to 是 x 的爸爸,直接把 x 旋上去
    • 如果 x 和它爸爸,爷爷在同一条直线就先旋父亲,再旋儿子
    • 若 x 和它爸爸,爷爷不在同一条直线上,旋两次 x 就好

    Insert

    在二叉树中找到它的位置,插入,然后把它转到根节点,就好了

    Delete

    找到目标节点,把它转到根,分情况讨论

    • 该节点有重复值,直接减
    • 它没有左右儿子:直接删
    • 它没有左儿子:把根置为右儿子
    • 它既有左儿子,也有右儿子:在左儿子中找到最大值,旋转到根,右儿子当做新根的右儿子

    Rank

    找到它的位置,根据子树大小确定它的排名

    Kth

    根据子树大小确定它的位置

    query pre(rec)

    和 Treap 一个样

    至于代码

    还没加工出来 = =

  • 相关阅读:
    Windows下搭建JSP开发环境
    ssh 学习笔记
    18 11 27 长连接 短链接
    18 11 26 用多进程 多线程 携程 实现 http 服务器的创建
    18 11 24 简单的http服务器
    关于 某个智慧树课堂的 机器与机器交流方法
    18 11 23 正则学习
    尝试解决 : Microsoft Visual C++ 14.0 is required 的问题
    18 11 20 网络通信 ----多任务---- 携程 ----生成器
    18 11 20 网络通信 ----多任务---- 携程 ----迭代器
  • 原文地址:https://www.cnblogs.com/Arielzz/p/14901366.html
Copyright © 2011-2022 走看看