【数据结构】FHQ Treap详解

FHQ Treap是什么?

FHQ Treap,又名无旋Treap,是一种不需要旋转的平衡树,是范浩强基于Treap发明的。FHQ Treap具有代码短,易理解,速度快的优点。(当然跟红黑树比一下就是……)至少它在OI中算是很优秀的数据结构了。

前置知识:

  • C++
  • 二叉搜索树的基本性质,下面会讲
  • 二叉堆

二叉搜索树的基本性质

很简单,就这几个。

  • 二叉搜索树中,每个结点都满足左子树的结点的值都小于等于自己的值,右子树的结点的值都大于自己的值,左右子树也是二叉搜索树。
  • 中序遍历二叉搜索树可以得到一个由这棵树的所有结点的值组成的有序序列。(即所有的值排序后的结果)

原理&代码实现

本文中,Treap就是指有旋Treap

FHQ Treap不是通过旋转来保持平衡的,而是通过两个函数splitmerge。顾名思义,split就是分裂,merge就是合并。当然,从最底层的原理来看,还不是这两个函数。FHQ Treap中的Treap代表Tree + Heap,也就是说,FHQ Treap会按二叉搜索树一样根据键值排序结点,并且随机赋给每个结点一个优先级,按照二叉堆的顺序排序结点(这里用大根堆)。Treap通过旋转,使平衡树同时满足这两个性质,从而达到平衡。而FHQ Treap通过调用merge函数时使平衡树满足堆序,实现原理与Treap不同。

结点信息

FHQ Treap是一个二叉树,所以可以写出这样的代码:

template <typename T, int MaxSize>
class FHQTreap
{
public:
    FHQTreap() { Seed = (int)(MaxSize * 565463ll % 2147483647); }    
    // ...
private:
    struct Node 
    {
        T Key;
        int Left, Right, Size, Priority;
    } Tree[MaxSize];
    int Seed, Total, Root;
    
    int random() { return Seed = (int)(Seed * 104831ll % 0x7fffffff); }
    
    void pushup(int root) {
        if(root != 0) {
            Tree[root].Size = Tree[Tree[root].Left].Size + Tree[Tree[root].Right].Size + 1; // + 1是要算上自己
        }
    }
    // ...
}

Node即结点,里面的Key就是要存的值,Priority即优先级。Seed就是随机数种子,在构造函数中初始化,random()会生成一个在int范围内的整数,作为结点的优先级。(我自己写随机数生成函数只是个人习惯)

构造新结点

int create(T key) {
    int root = ++Total;
    Tree[root].Key = key;
    Tree[root].Size = 1;
    Tree[root].Left = Tree[root].Right = 0;
    Tree[root].Priority = rad();
    return root;
}

create(T key)会初始化一个结点,并返回它的ID,大家也可以用指针实现。这里比较简单,就不多解释了。

split函数

split分为两种:

  • 按值分裂:根据一个值\(key\)把一棵树分裂成两棵树,一棵树的值全部小于等于\(key\),另外一棵全部大于\(key\)
  • 按大小分裂:根据一个值\(size\)分裂树,一棵的大小为\(size\),另外一棵为剩下的。

按值分裂

如上图。这里split函数简化了,只写了值。根据图可以看出,比\(25\)小的结点都被分裂到以\(x\)为根的树上&#x

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值