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 一个样

    至于代码

    还没加工出来 = =

  • 相关阅读:
    mysql 模糊查询LIKE 在tp中使用
    json字符串与 js对象互相转换
    1431. Kids With the Greatest Number of Candies
    1481. Least Number of Unique Integers after K Removals
    560. Subarray Sum Equals K
    1476. Subrectangle Queries
    1475. Final Prices With a Special Discount in a Shop
    网速和流量有什么关系
    计算网速的计算公式是什么
    php file_put_contents 函数的使用
  • 原文地址:https://www.cnblogs.com/Arielzz/p/14901366.html
Copyright © 2011-2022 走看看