一、源码学习
map是KV结构,而set是K结构,是用两棵树来实现吗?
template <class Key, class Compare, class Alloc = alloc>
class set {
public:
// typedefs:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
private:
typedef rb_tree<key_type, value_type, identity<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing set
};
template <class Key, class T, class Compare, class Alloc = alloc>
class map {
public:
typedef Key key_type;
typedef T data_type;
typedef T mapped_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
private:
typedef rb_tree<key_type, value_type, select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing map
};
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc = alloc>
class rb_tree {
protected:
typedef __rb_tree_node<Value> rb_tree_node;
}
template <class Value>
struct __rb_tree_node : public __rb_tree_node_base
{
typedef __rb_tree_node<Value>* link_type;
Value value_field;
};
可以看到这里是只用了一棵树来实现,这里的value用来存储有效数据
二、改造红黑树
我们看到上述map和set的实现底层,因此我们进行改造红黑树,以便我们能够更好的模拟实现出map与set
#pragma once
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
enum Colour
{
RED,
BLACK
};
template <class T>
struct RBTreeNode
{
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
Colour _col;
T _data;
RBTreeNode(const T& data)
: _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _col(RED)
, _data(data)
{}
};
// set RBTree<K, K, SetOfT>
// map RBTree<K, pair<K,V>, MapOfT>
template <class K, class T, class KeyOfT> // KeyOfT为了确保T是map还是set,因为插入的时候要比较大小,要确保是用K还是pair的first
struct RBTree
{
typedef RBTreeNode<T> Node;
public:
RBTree()
: _root(nullptr)
{}
/* bool Insert(const T& data)
{
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return true;
}
KeyOfT kot;
Node* parent = nullptr;
Node* cur = _root;
// 找到要插入的位置
while (cur)
{
if (kot(cur->_data) > kot(data))
{
parent = cur;
cur = cur->_left;
}
else if (kot(cur->_data) < kot(data))
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
// 找到该位置后进行插入
cur = new Node(data);
cur->_col = RED;
if (kot(cur->_data) > kot(data))
{
parent->_left = cur;
}
else
{
parent->_right = cur;
}
cur->_parent = parent;
// 接下来控制平衡
// 只有插入的节点和双亲节点都是红色才需要去进行处理
while (parent && parent->_col == RED)
{
Node* grandFather = parent->_parent;
if (parent == grandFather->_left) // parent在左侧的情况
{
Node* uncle = grandFather->_right;
// 情况1:叔叔存在且为红
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandFather->_col = RED;
cur = grandFather;
parent = cur->_parent;
}
// 情况2:叔叔不存在/叔叔存在且为黑
else
{
/*
单旋
g
p
c
双旋
g
p
c
*/
if (cur == parent->_left) // 单旋
{
RotateR(grandFather);
parent->_col = BLACK;
grandFather->_col = RED;
}
else // 双旋
{
RotateL(parent);
RotateR(grandFather);
cur->_col = BLACK;
grandFather->_col = RED;
}
break; // 旋转完后跳出循环
}
}
else // if (parent == grandFather->_left) // parent在右侧的情况
{
Node* uncle = grandFather->_left;
if (uncle && uncle->_col == RED)
{
// 变色+向上处理
parent->_col = uncle->_col = BLACK;
grandFather->_col = RED;
cur = grandFather;
parent = cur->_parent;
}
else
{
/*
单旋
g
p
c
双旋
g
p
c
*/
if (cur == parent->_right)
{
RotateL(grandFather);
parent->_col = BLACK;
grandFather->_col = RED;
}
else
{
RotateR(parent);
RotateL(grandFather);
cur->_col = BLACK;
grandFather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return true;
}*/
bool Insert(const T& data)
{
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return true;
}
KeyOfT kot;
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (kot(cur->_data) < kot(data))
{
parent = cur;
cur = cur->_right;
}
else if (kot(cur->_data) > kot(data))
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
cur = new Node(data);
cur->_col = RED; // 新增节点
if (kot(parent->_data) < kot(data))
{
parent->_right = cur;
cur->_parent = parent;
}
else
{
parent->_left = cur;
cur->_parent = parent;
}
// 控制平衡
while (parent && parent->_col == RED)
{
Node* grandfather = parent->_parent;
if (parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
// 1、uncle存在且为红
if (uncle && uncle->_col == RED)
{
// 变色+继续向上处理
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else // 2 + 3、uncle不存在/ 存在且为黑
{
// g
// p
// c
// g
// p
// c
if (cur == parent->_left)
{
// 单旋
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
// 双旋
RotateL(parent);
RotateR(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else // parent == grandfather->_right
{
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
// 变色+继续向上处理
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else // 2 + 3、uncle不存在/ 存在且为黑
{
// g
// p
// c
// g
// p
// c
if (cur == parent->_right)
{
RotateL(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateR(parent);
RotateL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return true;
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
{
subRL->_parent = parent;
}
Node* parentParent = parent->_parent;
subR->_left = parent;
parent->_parent = subR;
if (_root == parent)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
if (parentParent->_left == parent)
parentParent->_left = subR;
else
parentParent->_right = subR;
subR->_parent = parentParent;
}
}
void RotateR(Node * parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
Node* parentParent = parent->_parent;
subL->_right = parent;
parent->_parent = subL;
if (parent == _root)
{
_root = subL;
_root->_parent = nullptr;
}
else
{
if (parentParent->_left == parent)
parentParent->_left = subL;
else
parentParent->_right = subL;
subL->_parent = parentParent;
}
}
private:
Node* _root;
};
三、模拟实现map
namespace zmm
{
template <class K, class V>
class map
{
public:
// 添加一个仿函数
struct MapKeyOfT
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
bool insert(const pair<K, V>& kv)
{
return _t.Insert(kv);
}
private:
RBTree<K, pair<K, V>, MapKeyOfT> _t; // 第二个模板参数决定树里面存储的是什么
};
void test_map()
{
map<int, int> m;
m.insert(make_pair(3, 3));
m.insert(make_pair(5, 5));
m.insert(make_pair(1, 1));
m.insert(make_pair(8, 8));
}
}
四、模拟实现set
namespace zmm
{
template <class K>
class set
{
public:
struct SetKeyOfT
{
const K& operator()(const K& k)
{
return k;
}
};
bool insert(const K& key)
{
return _t.Insert(key);
}
private:
RBTree<K, K, SetKeyOfT> _t; // 第二个模板参数决定树里面存储的是什么
};
void test_set()
{
set<int> s;
s.insert(1);
s.insert(4);
s.insert(2);
s.insert(6);
s.insert(1);
}
}
五、红黑树的迭代器
红黑树迭代器++要完成中序遍历,这里可以参考之前的list模拟实现
迭代器的遍历的时候,通过++it,如何让it指向下一个位置(中序遍历)
++it:如果右子树不为空,中序的下一个右子树的最左节点
如果右树为空,说明我所在的子树已经访问完了,不断往上走,沿着到根的路径找孩子是父亲左的那个祖先,直到父亲为空就结束
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)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
Self& operator++()
{
if (_node->_right)
{
Node* min = _node->_right;
while (min->_left)
{
min = min->_left;
}
_node = min;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent->_parent;
}
_node = parent;
}
return *this;
}
};
这里要注意,我们是要对类模板里面的类型进行typedef,要加typename,因为类模板在实例化之前还什么都不是
完整的迭代器实现:
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)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
Self& operator++()
{
if (_node->_right)
{
Node* min = _node->_right;
while (min->_left)
{
min = min->_left;
}
_node = min;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
bool operator!=(const Self& s) const
{
return _node != s._node;
}
bool operator==(const Self& s) const
{
return _node == s._node;
}
Self& operator--()
{
// 左根右
// 访问左子树最右节点
if (_node->_left)
{
Node* max = _node->_left;
while (max->_right)
{
max = max->_right;
}
}
else // 左为空,往上更新
// 减减是倒着走,右根左,左为空了 就说明此时走完了
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_left)
{
cur = parent;
parent = parent->_parent;
}
// 要么parent为空要么为右
_node = parent;
}
return *this;
}
};
六、MyMap.h
#pragma once
#include "RBTree.h"
#include <string>
namespace zmm
{
template <class K, class V>
class map
{
public:
// 添加一个仿函数
struct MapKeyOfT
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
typedef typename RBTree<K, pair<K, V>, MapKeyOfT>::iterator iterator;
pair<iterator, bool> insert(const pair<K, V>& kv)
{
return _t.Insert(kv);
}
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
V& operator[](const K& key) // 返回value的引用
{
auto ret = _t.Insert(make_pair(key, V()));
return ret.first->second; // ret是pair是结构体,里面第一个成员是迭代器
}
private:
RBTree<K, pair<K, V>, MapKeyOfT> _t; // 第二个模板参数决定树里面存储的是什么
};
void test_map()
{
map<string, string> dict;
dict.insert(make_pair("sort", "排序"));
dict.insert(make_pair("string", "字符串"));
dict.insert(make_pair("map", "地图"));
dict["left"];
dict["left"] = "左边";
dict["map"] = "地图、映射";
auto it = dict.begin();
while (it != dict.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
cout << endl;
}
}
七、MySet.h
#pragma once
#include "RBTree.h"
namespace zmm
{
template <class K>
class set
{
public:
struct SetKeyOfT
{
const K& operator()(const K& k)
{
return k;
}
};
typedef typename RBTree<K, K, SetKeyOfT>::iterator iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
pair<iterator, bool> insert(const K& key)
{
return _t.Insert(key);
}
iterator find(const K& key)
{
return _t.Find(key);
}
private:
RBTree<K, K, SetKeyOfT> _t; // 第二个模板参数决定树里面存储的是什么
};
void test_set()
{
set<int> s;
s.insert(1);
s.insert(4);
s.insert(2);
s.insert(6);
s.insert(1);
set<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
set<int> copy(s);
for (auto e : copy)
{
cout << e << " ";
}
cout << endl;
}
}
八、RBTree.h
#pragma once
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
enum Colour
{
RED,
BLACK
};
template <class T>
struct RBTreeNode
{
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
Colour _col;
T _data;
RBTreeNode(const T& data)
: _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _col(RED)
, _data(data)
{}
};
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)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
Self& operator++()
{
if (_node->_right)
{
Node* min = _node->_right;
while (min->_left)
{
min = min->_left;
}
_node = min;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
bool operator!=(const Self& s) const
{
return _node != s._node;
}
bool operator==(const Self& s) const
{
return _node == s._node;
}
Self& operator--()
{
// 左根右
// 访问左子树最右节点
if (_node->_left)
{
Node* max = _node->_left;
while (max->_right)
{
max = max->_right;
}
}
else // 左为空,往上更新
// 减减是倒着走,右根左,左为空了 就说明此时走完了
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_left)
{
cur = parent;
parent = parent->_parent;
}
// 要么parent为空要么为右
_node = parent;
}
return *this;
}
};
// set RBTree<K, K, SetOfT>
// map RBTree<K, pair<K,V>, MapOfT>
template <class K, class T, class KeyOfT> // KeyOfT为了确保T是map还是set,因为插入的时候要比较大小,要确保是用K还是pair的first
struct RBTree
{
typedef RBTreeNode<T> Node;
public:
typedef RBTreeIterator<T, T&, T*> iterator;
iterator begin()
{
Node* min = _root;
while (min && min->_left)
{
min = min->_left;
}
return iterator(min);// 最左节点,因为是中序遍历
}
iterator end()
{
return iterator(nullptr);// 最后一个节点的下一位位置
}
RBTree()
: _root(nullptr)
{}
~RBTree()
{
Destroy(_root);
_root = nullptr;
}
RBTree(const RBTree<K, T, KeyOfT>& t) // 一棵树的拷贝
{
_root = Copy(t._root);
}
Node* Copy(Node* root)
{
if (root == nullptr)
{
return nullptr;
}
// 递归拷贝左子树
Node* newRoot = new Node(root->_data);
newRoot->_col = root->_col;
newRoot->_left = Copy(root->_left);
newRoot->_right = Copy(root->_right);
if (newRoot->_left)
{
newRoot->_left->_parent = newRoot;
}
if (newRoot->_right)
{
newRoot->_right->_parent = newRoot;
}
return newRoot;
}
void Destroy(Node* root)
{
if (root == nullptr)
{
return;
}
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
iterator Find(const K& key) // 只有T不知道key的类型
{
Node* cur = _root;
KeyOfT kot;
while (cur)
{
if (kot(cur->_data) < key)
{
cur = cur->_right;
}
else if (kot(cur->_data) > key)
{
cur = cur->_left;
}
else
{
return iterator(cur);
}
}
return end();
}
//bool Insert(const T& data)
//{
// if (_root == nullptr)
// {
// _root = new Node(data);
// _root->_col = BLACK;
// return true;
// }
// KeyOfT kot;
// Node* parent = nullptr;
// Node* cur = _root;
// // 找到要插入的位置
// while (cur)
// {
// if (kot(cur->_data) > kot(data))
// {
// parent = cur;
// cur = cur->_left;
// }
// else if (kot(cur->_data) < kot(data))
// {
// parent = cur;
// cur = cur->_right;
// }
// else
// {
// return false;
// }
// }
// // 找到该位置后进行插入
// cur = new Node(data);
// cur->_col = RED;
// if (kot(cur->_data) > kot(data))
// {
// parent->_left = cur;
// }
// else
// {
// parent->_right = cur;
// }
// cur->_parent = parent;
// // 接下来控制平衡
// // 只有插入的节点和双亲节点都是红色才需要去进行处理
// while (parent && parent->_col == RED)
// {
// Node* grandFather = parent->_parent;
// if (parent == grandFather->_left) // parent在左侧的情况
// {
// Node* uncle = grandFather->_right;
// // 情况1:叔叔存在且为红
// if (uncle && uncle->_col == RED)
// {
// parent->_col = uncle->_col = BLACK;
// grandFather->_col = RED;
// cur = grandFather;
// parent = cur->_parent;
// }
// // 情况2:叔叔不存在/叔叔存在且为黑
// else
// {
// /*
// 单旋
// g
// p
// c
// 双旋
// g
// p
// c
// */
// if (cur == parent->_left) // 单旋
// {
// RotateR(grandFather);
// parent->_col = BLACK;
// grandFather->_col = RED;
// }
// else // 双旋
// {
// RotateL(parent);
// RotateR(grandFather);
// cur->_col = BLACK;
// grandFather->_col = RED;
// }
// break; // 旋转完后跳出循环
// }
// }
// else // if (parent == grandFather->_left) // parent在右侧的情况
// {
// Node* uncle = grandFather->_left;
// if (uncle && uncle->_col == RED)
// {
// // 变色+向上处理
// parent->_col = uncle->_col = BLACK;
// grandFather->_col = RED;
// cur = grandFather;
// parent = cur->_parent;
// }
// else
// {
// /*
// 单旋
// g
// p
// c
// 双旋
// g
// p
// c
// */
// if (cur == parent->_right)
// {
// RotateL(grandFather);
// parent->_col = BLACK;
// grandFather->_col = RED;
// }
// else
// {
// RotateR(parent);
// RotateL(grandFather);
// cur->_col = BLACK;
// grandFather->_col = RED;
// }
// break;
// }
// }
// }
// _root->_col = BLACK;
// return true;
//}
pair<iterator, bool> Insert(const T& data)
{
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return make_pair(iterator(_root), true);
}
KeyOfT kot;
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (kot(cur->_data) < kot(data))
{
parent = cur;
cur = cur->_right;
}
else if (kot(cur->_data) > kot(data))
{
parent = cur;
cur = cur->_left;
}
else
{
return make_pair(iterator(cur), false);;
}
}
cur = new Node(data);
Node* newnode = cur;
cur->_col = RED; // 新增节点
if (kot(parent->_data) < kot(data))
{
parent->_right = cur;
cur->_parent = parent;
}
else
{
parent->_left = cur;
cur->_parent = parent;
}
// 控制平衡
while (parent && parent->_col == RED)
{
Node* grandfather = parent->_parent;
if (parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
// 1、uncle存在且为红
if (uncle && uncle->_col == RED)
{
// 变色+继续向上处理
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else // 2 + 3、uncle不存在/ 存在且为黑
{
// g
// p
// c
// g
// p
// c
if (cur == parent->_left)
{
// 单旋
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
// 双旋
RotateL(parent);
RotateR(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else // parent == grandfather->_right
{
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
// 变色+继续向上处理
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else // 2 + 3、uncle不存在/ 存在且为黑
{
// g
// p
// c
// g
// p
// c
if (cur == parent->_right)
{
RotateL(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateR(parent);
RotateL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return make_pair(iterator(newnode), true); // 把新增节点保存起来
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
{
subRL->_parent = parent;
}
Node* parentParent = parent->_parent;
subR->_left = parent;
parent->_parent = subR;
if (_root == parent)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
if (parentParent->_left == parent)
parentParent->_left = subR;
else
parentParent->_right = subR;
subR->_parent = parentParent;
}
}
void RotateR(Node * parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
Node* parentParent = parent->_parent;
subL->_right = parent;
parent->_parent = subL;
if (parent == _root)
{
_root = subL;
_root->_parent = nullptr;
}
else
{
if (parentParent->_left == parent)
parentParent->_left = subL;
else
parentParent->_right = subL;
subL->_parent = parentParent;
}
}
private:
Node* _root;
};