文章目录
- 1.搭建框架
- 1.1map
- 1.2set
- 1.3RBTree
- 1.4图解
- 2.代码剖析
- 2.1RBTree.h
- 2.2Map.h
- 2.3Set.h
- 2.4Test.cpp
1.搭建框架
1.1map
1.2set
1.3RBTree
1.4图解
2.代码剖析
2.1RBTree.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <functional>
#include <assert.h>
using namespace std;
enum Colour
{
RED,
BLACK,
};
template<class T>
struct RBTreeNode
{
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
T _data;
Colour _col;
RBTreeNode(const T& data)
: _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _data(data)
, _col(RED)
{
}
};
template<class T, class Ref, class Ptr>
struct RBTreeIterator
{
typedef RBTreeNode<T> Node;
typedef RBTreeIterator<T, Ref, Ptr> Self;
Node* _node;
RBTreeIterator(Node* node)
:_node(node)
{
}
RBTreeIterator(const RBTreeIterator<T, T&, T*>& it)
:_node(it._node)
{
}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
bool operator!=(const Self& s)
{
return _node != s._node;
}
Self& operator++()
{
if (_node->_right)
{
Node* subLeft = _node->_right;
while (subLeft->_left)
{
subLeft = subLeft->_left;
}
_node = subLeft;
}
else
{
Node* cp = _node;
Node* dad = cp->_parent;
while (dad && cp == dad->_right)
{
cp = dad;
dad = dad->_parent;
}
_node = dad;
}
return *this;
}
Self& operator--()
{
if (_node->_left)
{
Node* subRight = _node->_left;
while (subRight->_right)
{
subRight = subRight->_right;
}
_node = subRight;
}
else
{
Node* cp = _node;
Node* dad = cp->_parent;
while (dad && cp == dad->_left)
{
cp = dad;
dad = dad->_parent;
}
_node = dad;
}
return *this;
}
};
template<class K, class T, class GetKey>
class RBTree
{
typedef RBTreeNode<T> Node;
public:
~RBTree()
{
_Destroy(_root);
_root = nullptr;
}
public:
typedef RBTreeIterator<T, T&, T*> itertaor;
typedef RBTreeIterator<T, const T&, const T*> const_itertaor;
itertaor begin()
{
Node* cp = _root;
while (cp && cp->_left)
{
cp = cp->_left;
}
return itertaor(cp);
}
itertaor end()
{
return itertaor(nullptr);
}
const_itertaor begin() const
{
Node* cp = _root;
while (cp && cp->_left)
{
cp = cp->_left;
}
return const_itertaor(cp);
}
const_itertaor end() const
{
return const_itertaor(nullptr);
}
Node* Find(const K& key)
{
Node* cp = _root;
GetKey get;
while (cp)
{
if (get(cp->_data) < key)
{
cp = cp->_right;
}
else if (get(cp->_data) > key)
{
cp = cp->_left;
}
else
{
return cp;
}
}
return nullptr;
}
pair<itertaor, bool> Insert(const T& data)
{
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return make_pair(itertaor(_root), true);
}
GetKey get;
Node* dad = nullptr;
Node* cp = _root;
while (cp)
{
if (get(cp->_data) < get(data))
{
dad = cp;
cp = cp->_right;
}
else if (get(cp->_data) > get(data))
{
dad = cp;
cp = cp->_left;
}
else
{
return make_pair(itertaor(cp), false);
}
}
cp = new Node(data);
Node* tmp = cp;
if (get(dad->_data) > get(data))
{
dad->_left = cp;
}
else
{
dad->_right = cp;
}
cp->_parent = dad;
while (dad && dad->_col == RED)
{
Node* grandpa = dad->_parent;
assert(grandpa);
assert(grandpa->_col == BLACK);
if (grandpa->_left == dad)
{
Node* uncle = grandpa->_right;
if (uncle && uncle->_col == RED)
{
dad->_col = BLACK;
uncle->_col = BLACK;
grandpa->_col = RED;
cp = grandpa;
dad = cp->_parent;
}
else
{
if (cp == dad->_left)
{
RotateR(grandpa);
dad->_col = BLACK;
grandpa->_col = RED;
}
else
{
RotateL(dad);
RotateR(grandpa);
cp->_col = BLACK;
grandpa->_col = RED;
}
break;
}
}
else
{
Node* uncle = grandpa->_left;
if (uncle && uncle->_col == RED)
{
dad->_col = BLACK;
uncle->_col = BLACK;
grandpa->_col = RED;
cp = grandpa;
dad = cp->_parent;
}
else
{
if (cp == dad->_right)
{
RotateL(grandpa);
grandpa->_col = RED;
dad->_col = BLACK;
}
else
{
RotateR(dad);
RotateL(grandpa);
cp->_col = BLACK;
grandpa->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return make_pair(itertaor(tmp), true);
}
bool IsRBTree()
{
if (_root && _root->_col == RED)
{
cout << "根节点颜色错误!" << endl;
return false;
}
int certain = 0;
Node* cur = _root;
while (cur)
{
if (cur->_col == BLACK)
++certain;
cur = cur->_left;
}
return PrevJudge(_root, 0, certain);
}
int Height()
{
return _Height(_root);
}
private:
void _Destroy(Node* root)
{
if (root == nullptr)
{
return;
}
_Destroy(root->_left);
_Destroy(root->_right);
delete root;
}
int _Height(Node* root)
{
if (root == NULL)
return 0;
int leftH = _Height(root->_left);
int rightH = _Height(root->_right);
return leftH > rightH ? leftH + 1 : rightH + 1;
}
bool PrevJudge(Node* root, int BNcount, int& certain)
{
if (root == nullptr)
{
if (BNcount != certain)
{
cout << "性质4违例: 存在某一路径黑色节点的数量不等!" << endl;
return false;
}
return true;
}
if (root->_col == BLACK)
{
++BNcount;
}
if (root->_col == RED
&& root->_parent
&& root->_parent->_col == RED)
{
cout << "性质3违例: 存在连续红节点!" << endl;
return false;
}
return PrevJudge(root->_left, BNcount, certain)
&& PrevJudge(root->_right, BNcount, certain);
}
void RotateL(Node* dad)
{
Node* subR = dad->_right;
Node* subRL = subR->_left;
dad->_right = subRL;
if (subRL)
subRL->_parent = dad;
Node* grandpa = dad->_parent;
subR->_left = dad;
dad->_parent = subR;
if (grandpa == nullptr)
{
_root = subR;
_root->_parent = nullptr;
}
else
{
if (grandpa->_left == dad)
{
grandpa->_left = subR;
}
else
{
grandpa->_right = subR;
}
subR->_parent = grandpa;
}
}
void RotateR(Node* dad)
{
Node* subL = dad->_left;
Node* subLR = subL->_right;
dad->_left = subLR;
if (subLR)
subLR->_parent = dad;
Node* grandpa = dad->_parent;
subL->_right = dad;
dad->_parent = subL;
if (dad == _root)
{
_root = subL;
_root->_parent = nullptr;
}
else
{
if (grandpa->_left == dad)
{
grandpa->_left = subL;
}
else
{
grandpa->_right = subL;
}
subL->_parent = grandpa;
}
}
private:
Node* _root = nullptr;
};
2.2Map.h
#pragma once
#include "RBTree.h"
namespace ape
{
template<class K, class V>
class map
{
struct GetKeyMap
{
const K& operator()(const pair<const K, V>& pair)
{
return pair.first;
}
};
public:
typedef typename RBTree<K, pair<const K, V>, GetKeyMap>::itertaor iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
V& operator[](const K& key)
{
pair<iterator, bool> pair = _t.Insert(make_pair(key, V()));
return pair.first->second;
}
pair<iterator, bool> insert(const pair<const K, V>& pair)
{
return _t.Insert(pair);
}
private:
RBTree<K, pair<const K, V>, GetKeyMap> _t;
};
void test_map1()
{
map<string, string> m;
string a = "Eddie", b = "彭于晏";
m.insert(make_pair(a,b));
m.insert(make_pair("Tom", "汤姆"));
m.insert(make_pair("Jerry", "杰瑞"));
map<string, string>::iterator it = m.begin();
while (it != m.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
cout << endl;
for (auto& e : m)
{
cout << e.first << ":" << e.second << endl;
}
cout << endl;
}
void test_map2()
{
string s[] = { "陀螺", "陀螺", "洋娃娃", "陀螺", "洋娃娃", "洋娃娃", "陀螺",
"洋娃娃", "悠悠球", "洋娃娃", "悠悠球", "乐高" };
map<string, int> m;
for (auto& e : s)
{
m[e]++;
}
for (auto& e : m)
{
cout << e.first << ":" << e.second << endl;
}
}
}
2.3Set.h
#pragma once
#include "RBTree.h"
namespace ape
{
template<class K>
class set
{
struct GetKeySet
{
const K& operator()(const K& key)
{
return key;
}
};
public:
typedef typename RBTree<K, K, GetKeySet>::const_itertaor iterator;
typedef typename RBTree<K, K, GetKeySet>::const_itertaor const_iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
pair<iterator, bool> insert(const K& key)
{
return _t.Insert(key);
}
private:
RBTree<K, K, GetKeySet> _t;
};
void test_set()
{
int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
set<int> s;
for (auto e : a)
{
s.insert(e);
}
set<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
}
}
2.4Test.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <functional>
using namespace std;
#include "AVLTree.h"
#include "RBTree.h"
#include "Map.h"
#include "Set.h"
int main()
{
ape::test_set();
return 0;
}