码迷,mamicode.com
首页 > 其他好文 > 详细

splay简单入门

时间:2019-02-25 00:52:00      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:fat   log   入门   指针   oid   基本   复杂   是的   spl   

照刘汝佳黑书学了下$splay$, 简单总结一下.

$splay$每次操作不保证复杂度, 但均摊每次是$O(logn)$的.

$splay$基本思想是每个结点被访问时, 使用$AVL$的旋转操作把它移动到根.$splay$的旋转与$AVL$的区别主要是由于$splay$的旋转是自底向上的, 所以需要设置父亲指针, 而不像$AVL$树那样以儿子为轴旋转.

 

$splay$核心是函数$splay(x,S)$. 它的作用是保证splay结构的情况将$x$旋转到根, 旋转过程要分三种情况讨论.

1, 节点$x$是的父结点$y$是根节点.

这时, 若$x$是$y$的左儿子则右旋, 若$x$是$y$的右儿子则左旋.

2, 节点$x$的父节点$y$不是根节点, 且$x$与$y$同时是各自父节点的左孩子或者同时是各自父节点的右儿子.

这时, 同时右旋两次, 或者左旋两次.

3, 节点$x$的父节点$y$不是根节点, 且$x$与$y$一个是其父节点的左儿子, 另一个为父节点的右儿子.

这时, 先右旋后左旋, 或者先左旋后右旋

void splay(int& x, int& s) {
    int p; 
    while (father[x]) {
        p = father[x]; 
        if (!father[p]) {
            if(x == left[p]) RightRotate(x);
            else LeftRotate(x);
            break;
        }
        if (x == left[p]) {
            if(p == left[father[p]]) {
                RightRotate(p);
                RightRotate(x);
            }
            else { 
                RightRotate(x);
                LeftRotate(x);
            }
        }
        else {
            if(p == right[father[p]]) {
                LeftRotate(p);
                LeftRotate(x);
            } 
            else {
                LeftRotate(x);
                RightRotate(x);
            }                                                       
        }
    }
    s = x;
}

 

splay简单入门

标签:fat   log   入门   指针   oid   基本   复杂   是的   spl   

原文地址:https://www.cnblogs.com/uid001/p/10428709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!