算法导论 Treap

Treap是一种结合了二叉查找树和堆特性的数据结构,每个节点包含关键字key和随机优先级priority。当所有优先级和关键字都不同时,Treap确保了关键字的二叉查找树顺序和优先级的小根堆属性。这种结构在算法中有着独特的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



一棵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”的原因,因为它同时具有二叉查找树和堆的特征。


#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
struct TNode
{
    int priority;
    int value;
    TNode * left;
    TNode * right;
    TNode *parent;
    TNode()
    {
        priority = rand();
        left = NULL;
        right = NULL;
        parent = NULL;
    }
};

struct Tree
{
    TNode * root;
    Tree()
    {
        root = NULL;
    }
};

void treap_insert(int value,Tree&t);
void treap_insert_fixup(Tree&t,TNode *x);
void left_rotate(Tree &t,TNode *x);
void right_rotate(Tree&t,TNode*x);

void printTT(Tree &t);
void print(TNode *x);
int main ()
{
    //srand(time(NULL));

    Tree t;
    for (int i = 1;i < 14;i ++)
    {
        treap_insert(i,t);
    }
    printTT(t);
}

void treap_insert(int value,Tree&t)
{
    TNode * p = new TNode();
    p->value = value;

    TNode * r = t.root;
    TNode * s = NULL;

    if (NULL == t.root)
    {
        t.root = p;
        return ;
    }
    else
    {
        while (r != NULL)
        {
            s = r;
            if (r->value < value)
            {
                r = r->right;
            }
            else
            {
                r = r->left;
            }
        }
        if (s->value < value)
        {
            s->right = p;
        }
        else
        {
            s->left = p;
        }
        p->parent = s;
        treap_insert_fixup(t,p);
    }
}

void treap_insert_fixup(Tree&t,TNode *x)
{
    TNode * y = NULL;
    while (x != NULL && x->parent != NULL)
    {
        y = x->parent;
        if (x->priority > y->priority)
        {
            break;
        }
        else
        {
            if(x == y->left)
            {
                right_rotate(t,y);
            }
            else
            {
                left_rotate(t,y);
            }
        }
    }
}
void left_rotate(Tree&t,TNode*x)
{
    TNode * y = x->right;
    if (t.root == x)
    {
        t.root = y;
    }
    else if (x == x->parent->left)
    {
        x->parent->left = y;
    }
    else
    {
        x->parent->right = y;
    }
    y->parent = x->parent;

    x->right = y->left;
    if(x->right)
    {
        x->right->parent = x;
    }

    y->left = x;
    x->parent = y;
}
void right_rotate(Tree&t,TNode*x)
{
    TNode * y = x->left;
    if (t.root == x)
    {
        t.root = y;
    }
    else if (x == x->parent->left)
    {
        x->parent->left = y;
    }
    else
    {
        x->parent->right = y;
    }
    y->parent = x->parent;

    x->left = y->right;
    if(x->left)
    {
        x->left->parent = x;
    }

    y->right = x;
    x->parent = y;
}
void printTT(Tree&t)
{
    cout <<"************" <<endl;
    print(t.root);
    cout <<"************" <<endl;
}
void print(TNode*x)
{
    if (NULL != x)
    {
        cout << x->value << "  " << x->priority<<endl;
        print(x->left);
        print(x->right);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值