公司算法库中不希望包含STL,BOOST之类的库,很多基础算法都需要自己写。下边的代码是用红黑树实现的MAP模板类,测试无误,贴出来供参考。实现了插入·查找·删除等主要功能。因为没有加额外的容器,迭代器,所以速度比STL的快很多, 用20000000数据进行查找·删除·插入测试结果如下:
STL MAP:
Begin!
Insert Data ...
Insert End! time:47
Del Test ...
del End! time:28
Search Test ...
Search End! time:20
End!
MY MAP:
Begin!
Insert Data ...
Insert End! time:30
Del Test ...
del End! time:18
Search Test ...
Search End! time:11
End!
#ifndef NULL
#define NULL 0
#endif
template<class K, class V, class C>
class map
{
public:
explicit map();
~map(){}
public:
enum { BLACK, RED, NIL };
typedef struct
{
K k_value;
V v_value;
}Pair;
struct RBTNode
{
Pair Obj;
char Color;
RBTNode* Parent;
RBTNode* Lchild;
RBTNode* Rchild;
};
public:
void Insert(const Pair& pair);
Pair* Find(const K& kvalue);
Pair* operator [] (const K& kvalue);
void Erase(const K& kvalue);
void Clear();
protected:
void InsertFixup(RBTNode* newNode);
void DeleteFixup(RBTNode* node);
RBTNode* /
UncleNode(RBTNode* node) { return node->Parent == node->Parent->Parent->Lchild/
? node->Parent->Parent->Rchild : node->Parent->Parent->Lchild; }
RBTNode* /
BrotherNode(RBTNode* node) { return node == node->Parent->Lchild ? node->Parent->Rchild/
: node->Parent->Lchild; }
void RotateRight(RBTNode* node)
{
RBTNode* lchild = node->Lchild;
node->Lchild = lchild->Rchild;
node->Lchild->Parent = node;
lchild->Parent = node->Parent;
if(NULL == node->Parent)
_root = lchild;
else if(node == node->Parent->Rchild)
node->Parent->Rchild = lchild;
else
node->Parent->Lchild = lchild;
node->Parent = lchild;
lchild->Rchild = node;
}
void RotateLeft(RBTNode* node)
{
RBTNode* rchild = node->Rchild;
node->Rchild = rchild->Lchild;
node->Rchild->Parent = node;
rchild->Parent = node->Parent;
if(NULL == node->Parent)
_root = rchild;
else if(node == node->Parent->Rchild)
node->Parent->Rchild = rchild;
else
node->Parent->Lchild = rchild;
node->Parent = rchild;
rchild->Lchild = node;
}
protected:
RBTNode* _root;
int _size;
C _comp;
};
template<class K, class V, class C>
map<K,V,C>::map(void)
{
_root = new RBTNode;
_root->Parent = NULL;
_root->Color = NIL;
_size = 0;
}
template<class K, class V, class C>
typename map<K,V,C>::Pair* map<K,V,C>::Find(const K& kvalue)
{
RBTNode* tmpNode = _root;
while(tmpNode->Color != NIL)
{
if(!_comp(tmpNode->Obj.k_value, kvalue) && !_comp(kvalue, tmpNode->Obj.k_value))
{
return &tmpNode->Obj;
}
if(_comp(tmpNode->Obj.k_value, kvalue))
{
tmpNode = tmpNode->Rchild;
}
else
{
tmpNode = tmpNode->Lchild;
}
}
return NULL;
}
template<class K, class V, class C>
typename map<K,V,C>::Pair* map<K,V,C>::operator [](const K& kvalue)
{
return Find(kvalue);
}
template<class K, class V, class C>
void map<K,V,C>::Clear()
{
RBTNode* node = _root, *tmp;
while(NULL != node)
{
if(NIL == node->Color || NULL == node->Lchild && NULL == node->Rchild)
{
tmp = node;
node = node->Parent;
if(NULL != node)
{
if(tmp == node->Lchild)
node->Lchild = NULL;
else
node->Rchild = NULL;
}
delete tmp;
}
if(NULL != node)
{
if(NULL != node->Lchild)
node = node->Lchild;
else if(NULL != node->Rchild)
node = node->Rchild;
}
}
}
template<class K, class V, class C>
void map<K,V,C>::Insert(const Pair& pair)
{
RBTNode* tmpNode = _root;
while(tmpNode->Color != NIL)
{
if(!_comp(tmpNode->Obj.k_value, pair.k_value) && !_comp(pair.k_value, tmpNode->Obj.k_value))
{
tmpNode->Obj = pair;
return;
}
if(_comp(tmpNode->Obj.k_value, pair.k_value))
tmpNode = tmpNode->Rchild;
else
tmpNode = tmpNode->Lchild;
}
tmpNode->Color = RED;
tmpNode->Obj = pair;
tmpNode->Lchild = new RBTNode;
tmpNode->Rchild = new RBTNode;
tmpNode->Lchild->Parent = tmpNode;
tmpNode->Rchild->Parent = tmpNode;
tmpNode->Lchild->Color = NIL;
tmpNode->Rchild->Color = NIL;
InsertFixup(tmpNode);
}
template<class K, class V, class C>
void map<K,V,C>::InsertFixup(RBTNode* newNode)
{
if(NULL == newNode->Parent)
{
newNode->Color = BLACK;
return;
}
if(BLACK == newNode->Parent->Color)
return;
RBTNode* tmp = UncleNode(newNode);
if(RED == tmp->Color)
{
tmp->Color = BLACK;
newNode->Parent->Color = BLACK;
newNode->Parent->Parent->Color = RED;
InsertFixup(newNode->Parent->Parent);
return;
}
if(newNode == newNode->Parent->Lchild && newNode->Parent/
== newNode->Parent->Parent->Rchild)
{
RotateRight(newNode->Parent);
newNode = newNode->Rchild;
}
else if(newNode == newNode->Parent->Rchild && newNode->Parent/
== newNode->Parent->Parent->Lchild)
{
RotateLeft(newNode->Parent);
newNode = newNode->Lchild;
}
newNode->Parent->Color = BLACK;
newNode->Parent->Parent->Color = RED;
if(newNode == newNode->Parent->Lchild)
RotateRight(newNode->Parent->Parent);
else
RotateLeft(newNode->Parent->Parent);
}
template<class K, class V, class C>
void map<K,V,C>::Erase(const K& kvalue)
{
RBTNode* node = _root;
while(NIL != node->Color)
{
if(!_comp(kvalue, node->Obj.k_value) && !_comp(node->Obj.k_value, kvalue))
break;
if(_comp(node->Obj.k_value, kvalue))
node = node->Rchild;
else
node = node->Lchild;
}
if(NIL == node->Color)
return;
if(NIL == node->Rchild->Color && NIL == node->Lchild->Color)
{
delete node->Rchild;
delete node->Lchild;
if(RED == node->Color)
node->Color = NIL;
else
{
node->Color = NIL;
DeleteFixup(node);
}
}
else if(NIL != node->Lchild->Color)
{
RBTNode* tmpDel = node->Lchild, *replace;
while(NIL != tmpDel->Rchild->Color)
tmpDel = tmpDel->Rchild;
node->Obj = tmpDel->Obj;
replace = tmpDel->Rchild->Color != NIL ? tmpDel->Rchild : tmpDel->Lchild;
if(replace == tmpDel->Rchild)
delete tmpDel->Lchild;
else
delete tmpDel->Rchild;
replace->Parent = tmpDel->Parent;
if(replace->Parent == NULL)
_root = replace;
else if(tmpDel == tmpDel->Parent->Rchild)
tmpDel->Parent->Rchild = replace;
else
tmpDel->Parent->Lchild = replace;
if(BLACK == tmpDel->Color)
{
if(RED == replace->Color)
replace->Color = BLACK;
else
DeleteFixup(replace);
}
delete tmpDel;
}
else
{
RBTNode* tmpDel = node->Rchild, *replace;
while(NIL != tmpDel->Lchild->Color)
tmpDel = tmpDel->Lchild;
node->Obj = tmpDel->Obj;
replace = tmpDel->Rchild->Color != NIL ? tmpDel->Rchild : tmpDel->Lchild;
if(replace == tmpDel->Rchild)
delete tmpDel->Lchild;
else
delete tmpDel->Rchild;
replace->Parent = tmpDel->Parent;
if(replace->Parent == NULL)
_root = replace;
else if(tmpDel == tmpDel->Parent->Rchild)
tmpDel->Parent->Rchild = replace;
else
tmpDel->Parent->Lchild = replace;
if(BLACK == tmpDel->Color)
{
if(RED == replace->Color)
replace->Color = BLACK;
else
DeleteFixup(replace);
}
delete tmpDel;
}
}
template<class K, class V, class C>
void map<K,V,C>::DeleteFixup(RBTNode* node)
{
if(NULL == node->Parent)
return;
RBTNode* brother = BrotherNode(node);
if(RED == brother->Color)
{
node->Parent->Color = RED;
brother->Color = BLACK;
if(node == node->Parent->Lchild)
RotateLeft(node->Parent);
else
RotateRight(node->Parent);
}
brother = BrotherNode(node);
if(RED != node->Parent->Color &&/
RED != brother->Color &&/
RED != brother->Lchild->Color &&/
RED != brother->Rchild->Color)
{
brother->Color = RED;
DeleteFixup(node->Parent);
}
else
{
if(RED == node->Parent->Color &&/
RED != brother->Color &&/
RED != brother->Lchild->Color &&/
RED != brother->Rchild->Color)
{
brother->Color = RED;
node->Parent->Color = BLACK;
}
else
{
if(node == node->Parent->Lchild &&/
brother->Lchild->Color == RED &&/
brother->Rchild->Color != RED)
{
brother->Color = RED;
brother->Lchild->Color = BLACK;
RotateRight(brother);
}
else if(node == node->Parent->Rchild &&/
brother->Lchild->Color != RED &&/
brother->Rchild->Color == RED)
{
brother->Color = RED;
brother->Rchild->Color = BLACK;
RotateLeft(brother);
}
brother = BrotherNode(node);
brother->Color = node->Parent->Color;
node->Parent->Color = BLACK;
if(node == node->Parent->Lchild)
{
brother->Rchild->Color = BLACK;
RotateLeft(node->Parent);
}
else
{
brother->Lchild->Color = BLACK;
RotateRight(node->Parent);
}
}
}
}
#endif
基础不好的童鞋注意:模板中的class c是要自己实现的哟,比如:
class cmp
{
public:
bool operator()(const Point& a, const Point& b) const
{
return a.x < b.x;
}
};