zoukankan      html  css  js  c++  java
  • 从零开始“发明”Treap

    首先考虑我们要解决的问题:让一个不断插入新元素的BST保持平衡,即深度控制在$log n$级别。

    众所周知,一个随机顺序插入的BST是平衡的(容易发现随机插入构建的树深度等价于进行一次随机快速排序的最大递归层数,既选一个根最先插入,然后递归下去),所以我们想做的大概就是让每次插入后,树的结构和随机插入构成的树一样。

    当然,一种巧妙(或者更加自然)的方法是每插入$sqrt{n}$个元素后线性重构整颗树做到根号复杂度,或者根据树的结构随时重构(也就是“替罪羊树”,可以做到$n log n$的复杂度),在这里先不讨论。

    所以,最直接的想法就是给每个点一个随机权值作为他的相对插入顺序,这样所有新加入的节点也相当于是“随机插入”的。而不难发现要让树的结构满足条件,我们只需要在满足BST结构的同时让随机权值满足堆的性质,也就是父亲节点一定比子结点先插入。这样,我们就自然的“发明”了Treap。接下来只需要找到一种操作使我们能在不破坏BST性质的同时实现堆的“上移”操作,而这就是zig-zag旋转操作。这个操作是$O(1)$的,所以维护这颗树的复杂度和维护一个堆是一样的。

    事实上,我们考虑构造BST的另一种表述:给定一颗二叉树的中序遍历, 构造一颗对应的二叉树使得其深度尽量小。我们知道,对于一颗二叉树,只需要确定它的中序遍历与后序遍历就可以唯一确定这棵树。具体过程就是后序遍历的最后一个点一定是树根,我们找到根在中序遍历里的位置以后就可以把中序遍历中两侧的点分治处理。也就是说,最终获得的树结构满足父亲在后序遍历中的位置大于儿子,既每个点在后序遍历中出现的位置在原树中满足堆的性质。

    所以,我们随机“插入顺序”其实就是随机这棵树的后序遍历。

  • 相关阅读:
    损失函数绘图
    nexus+maven配置
    tomcat 修改端口号
    Git 删除远程仓库文件,文件夹
    git 删除远程分支 branch
    IBM WebSphere Commerce之订单处理
    Python+Selenium自动化
    git push 时 rejected
    IBM WebSphere Commerce初探
    NetApp存储
  • 原文地址:https://www.cnblogs.com/Cubelia/p/13471425.html
Copyright © 2011-2022 走看看