公司算法库中不希望包含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 _MAP_H_ #define _MAP_H_ #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是要自己实现的哟,比如:
struct Point { int x; int y; }; class cmp { public: bool operator()(const Point& a, const Point& b) const { return a.x < b.x; } };