一个SBT模板。(平衡BST)
据说插入效率比红黑树还高= =
其中Maintain函数的效率可以进一步改进
(话说也就一个Maintain能优化其它的都跟标准BST一毛一样= =)
想用的话直接拷贝过去用把= =
API都很清楚把= =
//KeyType must be comparable!!!!!!!
//overload both operator '>' and '<'
//or you will get a compilation error
template<typename KeyType,typename ValType>
class Size_Balanced_Tree {
struct node {
int Size;//important!!!
//cnt the number of child nodes
KeyType key;
ValType val;
node *lchild, *rchild;
node(KeyType k, ValType v) {
lchild = 0, rchild = 0; Size = 0;
val = v; key = k;
}
};
node *root;
inline int SizeOf(node *&target) {
return target ? target->Size : 0;
}
void Lrotate(node *&target) {
node *temp = target->lchild;
target->lchild = temp->rchild;
temp->rchild = target;
temp->Size = target->Size;
target->Size = SizeOf(target->lchild) + SizeOf(target->rchild) + 1;
target = temp;
}
void Rrotate(node *&target) {
node *temp = target->rchild;
target->rchild = temp->lchild;
temp->lchild = target;
temp->Size = target->Size;
target->Size = SizeOf(target->lchild) + SizeOf(target->rchild) + 1;
target = temp;
}
void Maintain(node *& target) {
if (target->lchild != NULL) {
if (SizeOf(target->rchild) < SizeOf(target->lchild->lchild))
Lrotate(target);
else if (SizeOf(target->rchild) < SizeOf(target->lchild->rchild)) {
Rrotate(target->lchild);
Lrotate(target);
}Maintain(target->lchild);
}
if (target->rchild != NULL) {
if (SizeOf(target->lchild) < SizeOf(target->rchild->rchild))
Rrotate(target);
else if (SizeOf(target->lchild) < SizeOf(target->rchild->lchild)) {
Lrotate(target->rchild);
Rrotate(target);
}Maintain(target->rchild);
}
return;
}
void insert(node *&target, KeyType &key, ValType &val) {
if (!target) {
target = new node(key, val);
return;
}
target->Size++;
if (key > target->key)insert(target->rchild, key, val);
else if (key != target->key)insert(target->lchild, key, val);
else return;
Maintain(target);
}
ValType query(node *&target, KeyType key) {
if (target == NULL)
return 0;
if (target->key == key)return target->val;
else if (target->key < key)return query(target->rchild, key);
else return query(target->lchild, key);
}
public:
Size_Balanced_Tree() {
root = 0;
}
//returns the value of the node with the max key in the whole tree
ValType max() {
node *scout = root;
while (scout->rchild != NULL)
scout = scout->rchild;
return scout->val;
}
//= =
ValType min() {
node *scout = root;
while (scout->lchild != NULL)
scout = scout->lchild;
return scount->val;
}
//returns the rank(from min) of the key in the tree
int rank(KeyType key) {
node *scout = root;
int r = 0;
while (scout->key != key) {
if (scout->key < key) {
r += scout->lchild->Size + 1;
scout = scout->rchild;
}
else if (scout->key > key)scout = scout->lchild;
}
r += scout->lchild->Size + 1;
return r;
}
//anything not clear= =?
void insert(KeyType key, ValType val) {
insert(root, key, val);
}
ValType query(KeyType key) {
return query(root, key);
}
};