扩充的数据结构-Order Statistic Tree

Order Statistic Tree:基于红黑树的实现与更新
本文介绍了Order Statistic Tree的概念,它以红黑树为基础,每个节点包含一个额外的整数域记录子树节点数量。讨论了如何实现order statistic功能,如OS_select和OS_rank,并探讨了在插入和删除操作中如何动态更新子树大小,通过在节点内直接维护size属性,确保在旋转操作时保持正确性。

(1)以红黑树作为underlying data structure,在树的每个节点增加一个int域储存该节点的subtree节点个数(包含自身)

node_size(x) = node_size(left[x]) + node_size(right[x]) + 1;

设nil节点的node_size返回0;

typedef struct node{
    int key;    int color;  //Augment field: the number of all nodes in the subtree of current node, including its self
    struct node *left;  struct node *right;  struct node *p;
    int node_size();
}*pnode, node;
node sentinel = {0,1,NULL,NULL,NULL};  //初始化列表赋值,initializer_list
pnode nil= &sentinel;

int node::node_size(){
    if(this != nil)
        return left->node_size()+right->node_size()+1;
    else
        return 0;
}

测试:

void test_RBtree(){
    vector<int> A = {7,3,18,10,22,8,11,26};
    pnode root = nil;
    for(int i = 0; i < A.size(); i++){
        pnode z = (pnode)malloc(sizeof(node));
        z->key = A[i];  z->left = nil;  z->right = nil;
        RB_insert(root, z);
    }

    inorder_walk(root);
    cout<<endl;

    pnode z = (pnode)malloc(sizeof(node));   z->left = nil;  z->right = nil;  z->key = 15;
    RB_insert(root, z);
    pnode rr = find_root(z);

    inorder_walk(rr);
    cout<<endl;
    cout<<rr->node_size()<<endl;
}

结果:


(2)order statistic:OS_select()以及OS_rank:

int OS_rank(pnode x){
    int r = x->right->node_size();
    while(x == x->p->right)
        x = x->p;
    return x->node_size()-r;
}

pnode OS_select(pnode root, int rank){
    if(root->node_size() >= rank){
        int r = root->right->node_size();
        if(root->node_size()-r == rank)
            return root;
        if(root->node_size()-r > rank)
            return OS_select(root->left, rank);
        if(root->node_size()-r < rank)
            return OS_select(root->right, rank-root->node_size()+r);
    }
    return nil; //如果给出的rank值超出树的大小,则返回nil指针
}

(3)Update subtree sizes when inserting or deleting, 与第(1)种方法不同,在node内直接定义一个int size域,对RB_insert进行修改,使其在插入时就直接修改各个相关节点的size大小。注意rotation操作需要修改size大小,时间复杂度为O(1):just look at children size. (待完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值