zoukankan      html  css  js  c++  java
  • Treap树

        Treap树算是一种简单的优化策略,这名字大家也能猜到,树和堆的合体,其实原理比较简单,在树中维护一个"优先级“,”优先级“

    采用随机数的方法,但是”优先级“必须满足根堆的性质,当然是“大根堆”或者“小根堆”都无所谓,比如下面的一棵树:

    从树中我们可以看到:

    ①:节点中的key满足“二叉查找树”。

    ②:节点中的“优先级”满足小根堆。

         一棵treap是一棵修改了结点顺序的二叉查找树,如图,显示一个例子,通常树内的每个结点x都有一个关键字值key[x],另外,还要为结点分配priority[x],它是一个独立选取的随机数。
    假设所有的优先级是不同的,所有的关键字也是不同的。treap的结点排列成让关键字遵循二叉查找树性质,并且优先级遵循最小堆顺序性质:
    1.如果v是u的左孩子,则key[v] < key[u].
    2.如果v是u的右孩子,则key[v] > key[u].
    3.如果v是u的孩子,则priority[u] > priority[u].
    这两个性质的结合就是为什么这种树被称为“treap”的原因,因为它同时具有二叉查找树和堆的特征。


    用以下方式考虑treap会有帮助。假设插入关联关键字的结点x1,x2,...,xn到一棵treap内。结果的treap是将这些结点以它们的优先级(随机选取)的顺序插入一棵正常的二叉查找树形成的,亦即priority[xi] < priority[xj]表示xi在xj之前被插入。
    在算法导论的12.4节中,其证明了随机构造的二叉查找树的期望高度为O(lgn),因而treap的期望高度亦是O(lgn)。

    treap插入操作:
    1.按照二叉树的插入方法,将结点插入到树中
    2.根据堆的性质(我们这里为最小堆)和优先级的大小调整结点位置。

    treap删除操作:
    1.找到相应的结点
    2.若该结点为叶子结点,则直接删除;
    若该结点为只包含一个叶子结点的结点,则将其叶子结点赋值给它;
    若该结点为其他情况下的节点,则进行相应的旋转,直到该结点为上述情况之一,然后进行删除。

    旋转主要涉及到右旋转的左旋转,下面把右旋转的图画在下面:

  • 相关阅读:
    Java 开发者不容错过的 12 种高效工具
    10个基于 Ruby on Rails 构建的顶级站点
    当 ITOA 遇上 OneAlert,企业可以至少每年节省 3600 小时!
    年度十佳 DevOps 博客文章(前篇)
    如何使用 Java8 实现观察者模式?(下)
    企业处理事件风暴的 2 种最佳管理方法
    移动开发:初学 iOS-UIViewController 心得
    如何使用 Java8 实现观察者模式?(上)
    世界级的安卓测试开发流!
    PHP全栈学习笔记19
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/5617129.html
Copyright © 2011-2022 走看看