使用红黑树实现的map

公司算法库中不希望包含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; } };

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以帮你实现一个基于红黑树Map数据结构。下面是一个简单的C++代码示例: ```cpp #include <iostream> enum Color { RED, BLACK }; template <typename K, typename V> struct Node { K key; V value; Color color; Node* left; Node* right; Node* parent; // 构造函数 Node(const K& k, const V& v, Color c = RED) : key(k), value(v), color(c), left(nullptr), right(nullptr), parent(nullptr) {} }; template <typename K, typename V> class RBTreeMap { public: RBTreeMap() : root(nullptr) {} // 向红黑树中插入键值对 void insert(const K& key, const V& value) { Node<K, V>* node = new Node<K, V>(key, value); if (root == nullptr) { root = node; node->color = BLACK; } else { Node<K, V>* curr = root; Node<K, V>* parent = nullptr; while (curr != nullptr) { parent = curr; if (key < curr->key) curr = curr->left; else if (key > curr->key) curr = curr->right; else { curr->value = value; // 更新值 return; } } node->parent = parent; if (key < parent->key) parent->left = node; else parent->right = node; insertFixup(node); } } // 查找指定键的值 V find(const K& key) const { Node<K, V>* curr = root; while (curr != nullptr) { if (key < curr->key) curr = curr->left; else if (key > curr->key) curr = curr->right; else return curr->value; } return V(); // 未找到,返回默认值 } private: Node<K, V>* root; // 对红黑树进行修复以维持红黑树的性质 void insertFixup(Node<K, V>* node) { while (node->parent != nullptr && node->parent->color == RED) { if (node->parent == node->parent->parent->left) { Node<K, V>* uncle = node->parent->parent->right; if (uncle != nullptr && uncle->color == RED) { node->parent->color = BLACK; uncle->color = BLACK; node->parent->parent->color = RED; node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rotateLeft(node); } node->parent->color = BLACK; node->parent->parent->color = RED; rotateRight(node->parent->parent); } } else { Node<K, V>* uncle = node->parent->parent->left; if (uncle != nullptr && uncle->color == RED) { node->parent->color = BLACK; uncle->color = BLACK; node->parent->parent->color = RED; node = node->parent->parent; } else { if (node == node->parent->left) { node = node->parent; rotateRight(node); } node->parent->color = BLACK; node->parent->parent->color = RED; rotateLeft(node->parent->parent); } } } root->color = BLACK; } // 左旋 void rotateLeft(Node<K, V>* node) { Node<K, V>* rightChild = node->right; node->right = rightChild->left; if (rightChild->left != nullptr) rightChild->left->parent = node; rightChild->parent = node->parent; if (node->parent == nullptr) root = rightChild; else if (node == node->parent->left) node->parent->left = rightChild; else node->parent->right = rightChild; rightChild->left = node; node->parent = rightChild; } // 右旋 void rotateRight(Node<K, V>* node) { Node<K, V>* leftChild = node->left; node->left = leftChild->right; if (leftChild->right != nullptr) leftChild->right->parent = node; leftChild->parent = node->parent; if (node->parent == nullptr) root = leftChild; else if (node == node->parent->left) node->parent->left = leftChild; else node->parent->right = leftChild; leftChild->right = node; node->parent = leftChild; } }; int main() { RBTreeMap<int, std::string> map; map.insert(1, "one"); map.insert(2, "two"); map.insert(3, "three"); map.insert(4, "four"); std::cout << map.find(2) << std::endl; // 输出: two std::cout << map.find(5) << std::endl; // 输出: 空字符串(默认值) return 0; } ``` 这个示例使用红黑树实现了一个简单的Map数据结构。你可以使用`insert`方法向Map中插入键值对,使用`find`方法查找指定键的值。注意,这只是一个简单的实现,还可以根据需要进行扩展和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值