(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. (待完成)