一、键值对
键值对是用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息
SGI-STL中关于键值对的定义:
template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(): first(T1()), second(T2())
{}
pair(const T1& a, const T2& b): first(a), second(b)
{}
};
二、红黑树实现set和map
通过查阅SGI-STL,我们知道set和map的底层均是使用红黑树实现的,只不过set存储的是key,而map存储的是key_value
2.1 红黑树的迭代器
迭代器的好处是可以方便遍历,是数据结构的底层实现与用户透明。如果想要给红黑树增加迭代器,需要考虑以前问题:
- begin()与end()
STL明确规定,begin()与end()代表的是一段前闭后开的区间,而对红黑树进行中序遍历后,可以得到一个有序的序列,因此:begin()可以放在红黑树中最小节点(即最左侧节点)的位置,end()放在最大节点(最右侧节点)的下一个位置,关键是最大节点的下一个位置在哪块? 能否给成nullptr呢?答案是行不通的,因为对end()位置的迭代器进行- -操作,必须要能找最后一个元素,此处就不行,因此最好的方式是将end()放在头结点的位置
- operator++()与operator- -()
2.2 红黑树的改造
2.2 改造后的红黑树的整体框架
//节点颜色
enum Colour
{
RED,
BLACK
};
//红黑树的节点
//K是用来查找的,T是用来插入的
//set中V是key,map中T是pair<key,value>
template<class T>
struct RBTreeNode
{
T _t;//data
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
Colour _col;
RBTreeNode(const T& t = T(),Colour col=RED)
:_t(t),
_left(nullptr),
_right(nullptr),
_parent(nullptr),
_col(col)
{}
};
//红黑树
template<class K, class T,class KeyOfT>
class RBTree
{
typedef RBTreeNode< T> Node;
public:
private:
Node* LeftMost()//最左节点
{
Node* MostLeftChild = _header->_parent;
while (MostLeftChild->_left)
{
MostLeftChild = MostLeftChild->_left;
}
return MostLeftChild;
}
Node* RightMost()//最右节点
{
Node* MostRightChild = _header->_parent;
while (MostRightChild->_right)
{
MostRightChild = MostRightChild->_right;
}
return MostRightChild;
}
Node* _header;//头结点
2.2.1 改造后的正向迭代器与反向迭代器
//红黑树的正向迭代器
template<class T,class Ref,class Ptr>
struct RBTreeIterator
{
typedef RBTreeNode<T> Node;
Node* _node;//要操作的节点
RBTreeIterator(Node* node):_node(node){}
typedef RBTreeIterator Self;
//++it
Self& operator++()
{
Node* cur = _node;
if (cur->_right)
{
Node* LeftMost = cur->_right;
while (LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
_node = LeftMost;
}
else
{
Node* parent = cur->_parent;
while (parent->_right == cur)
{
cur = parent;
parent = cur->_parent;
}
_node=parent;
}
return *this;
}
//it++
Self operator++(int)
{
Self temp(*this);
++*this;
return temp;
}
//--it
Self& operator--()
{
Node* cur = _node;
//end()时
if (_node->_parent->_parent == _node && _node->_col == RED)
{
_node = _node->_right;
}
else if (cur->_left)
{
Node* RightMost = cur->_left;
while (RightMost->_right)
{
RightMost = RightMost->_right;
}
_node = RightMost;
}
else
{
Node* parent = cur->_parent;
while ( parent->_left == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
//it--
Self operator--(int)
{
Self temp(*this);
--*this;
return temp;
}
Ref operator*()
{
return _node->_t;
}
Ptr operator->()
{
return &_node->_t;
}
bool operator!=(const Self& it)
{
return _node != it._node;
}
bool operator==(const Self& it)
{
return _node == it._node;
}
};
//红黑树的反向迭代器
template<class T, class Ref, class Ptr>
struct RBTreeReverseIterator
{
typedef RBTreeNode<T> Node;
Node* _node;//要操作的节点
RBTreeReverseIterator(Node* node) :_node(node) {}
typedef RBTreeReverseIterator Self;
//++it
Self& operator--()
{
Node* cur = _node;
if (cur->_right)
{
Node* LeftMost = cur->_right;
while (LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
_node = LeftMost;
}
else
{
Node* parent = cur->_parent;
while (parent->_right == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
//it++
Self operator++(int)
{
Self temp(*this);
++*this;
return temp;
}
//--it
Self& operator++()
{
Node* cur = _node;
//end()时
if (_node->_parent->_parent == _node && _node->_col == RED)
{
_node = _node->_right;
}
else if (cur->_left)
{
Node* RightMost = cur->_left;
while (RightMost->_right)
{
RightMost = RightMost->_right;
}
_node = RightMost;
}
else
{
Node* parent = cur->_parent;
while (parent->_left == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
//it--
Self operator--(int)
{
Self temp(*this);
--*this;
return temp;
}
Ref operator*()
{
return _node->_t;
}
Ptr operator->()
{
return &_node->_t;
}
bool operator!=(const Self& it)
{
return _node != it._node;
}
bool operator==(const Self& it)
{
return _node == it._node;
}
};
2.2.2 改造后的查找
iterator find(const K& key) const
{
Node* cur = _header->_parent;//指向根节点
while (cur)
{
if (key < KeyOfT()(cur->_t))
{
cur = cur->_left;
}
else if (key > KeyOfT()(cur->_t))
{
cur = cur->_right;
}
else
{
return iterator(cur);
}
}
return iterator(_header);
}
2.3.3 改造后的插入
pair<iterator,bool> insert(const T& t)
{
if (_header->_parent == nullptr)
{
_header->_parent = new Node(t);
_header->_parent->_col = BLACK;
_header->_parent->_parent = _header;
return { iterator(_header->_parent),true };
}
//查找结点
Node* parent = _header;
Node* cur = _header->_parent;
while (cur)
{
if (KeyOfT()(t) < KeyOfT()(cur->_t))
{
parent = cur;
cur = cur->_left;
}
else if (KeyOfT()(t) > KeyOfT()(cur->_t))
{
parent = cur;
cur = cur->_right;
}
else
{
return { iterator(cur), false };
}
}
//插入节点
cur = new Node(t);
cur->_parent = parent;
if (KeyOfT()(t) < KeyOfT()(parent->_t))
parent->_left = cur;
else
parent->_right = cur;
//保存cur,留待返回
Node* ret = cur;
//调整颜色
//情况一:parent存在且为黑,不需要调整
//情况二:parent存在且为红,需要调整
while (parent!=_header && parent->_col == RED)
{
//确定 g 和 u 节点
Node* grandfather = parent->_parent;
Node* uncle = nullptr;
if (parent == grandfather->_left)
uncle = grandfather->_right;
else
uncle = grandfather->_left;
//在情况二下又有如下情况:
//情况1:unclude存在且为红
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
//继续向上调整
cur = grandfather;
parent = cur->_parent;
}
//情况2:uncle不存在或uncle为黑
else if (!uncle || uncle->_col == BLACK)
{
//parent 是 grandfather 的左孩子
if (parent == grandfather->_left)
{
//cur 是 parent 的左孩子
if (cur == parent->_left)
{
//旋转加变色
RotateRight(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
//cur 是 parent 的右孩子
else
{
//旋转加变色
RotateLeftThenRight(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
}
//parent 是 grandfather 的右孩子
else
{
//cur 是 parent 的左孩子
if (cur == parent->_left)
{
//旋转加变色
RotateRightThenLeft(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
//cur 是 parent 的右孩子
else
{
//旋转加变色
RotateLeft(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
}
break;//调整好能退出了
}
else
{
assert(false);//逻辑错误,理论上不可能走到
}
}
_header->_parent->_col = BLACK;
_header->_left = LeftMost();
_header->_right = RightMost();
return { iterator(ret), true };
}
private:
void RotateLeft(Node* parent)
{
//保存节点,后面链接
Node* parentparent = parent->_parent;
Node* sub = parent->_right;
Node* subleft = sub->_left;
//重新链接
parent->_right = subleft;
if (subleft)
subleft->_parent = parent;
sub->_left = parent;
parent->_parent = sub;
//和上面的节点链接
if (parentparent == _header)
{
//说明parent原来是根节点
_header->_parent = sub;
sub->_parent = _header;
}
else
{
if (parentparent->_left == parent)
{
//原来是上面节点的左子树
parentparent->_left = sub;
}
else
{
parentparent->_right = sub;
}
sub->_parent = parentparent;
}
}
void RotateRight(Node* parent)
{
//保存节点,后面链接
Node* parentparent = parent->_parent;
Node* sub = parent->_left;
Node* subright = sub->_right;
//重新链接
parent->_left = subright;
if (subright)
subright->_parent = parent;
sub->_right = parent;
parent->_parent = sub;
//和上面的节点链接
if (parentparent == _header)
{
//说明parent原来是根节点
_header->_parent = sub;
sub->_parent = _header;
}
else
{
if (parentparent->_left == parent)
{
//原来是上面节点的左子树
parentparent->_left = sub;
}
else
{
parentparent->_right = sub;
}
sub->_parent = parentparent;
}
}
void RotateLeftThenRight(Node* parent)
{
RotateLeft(parent->_left);
RotateRight(parent);
}
void RotateRightThenLeft(Node* parent)
{
RotateRight(parent->_right);
RotateLeft(parent);
}
2.3.4 改造后的源码
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
//节点颜色
enum Colour
{
RED,
BLACK
};
//红黑树的节点
//K是用来查找的,T是用来插入的
//set中V是key,map中T是pair<key,value>
template<class T>
struct RBTreeNode
{
T _t;//data
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
Colour _col;
RBTreeNode(const T& t = T(),Colour col=RED)
:_t(t),
_left(nullptr),
_right(nullptr),
_parent(nullptr),
_col(col)
{}
};
//红黑树的迭代器
template<class T,class Ref,class Ptr>
struct RBTreeIterator
{
typedef RBTreeNode<T> Node;
Node* _node;//要操作的节点
RBTreeIterator(Node* node):_node(node){}
typedef RBTreeIterator Self;
//++it
Self& operator++()
{
Node* cur = _node;
if (cur->_right)
{
Node* LeftMost = cur->_right;
while (LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
_node = LeftMost;
}
else
{
Node* parent = cur->_parent;
while (parent->_right == cur)
{
cur = parent;
parent = cur->_parent;
}
_node=parent;
}
return *this;
}
//it++
Self operator++(int)
{
Self temp(*this);
++*this;
return temp;
}
//--it
Self& operator--()
{
Node* cur = _node;
//end()时
if (_node->_parent->_parent == _node && _node->_col == RED)
{
_node = _node->_right;
}
else if (cur->_left)
{
Node* RightMost = cur->_left;
while (RightMost->_right)
{
RightMost = RightMost->_right;
}
_node = RightMost;
}
else
{
Node* parent = cur->_parent;
while ( parent->_left == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
//it--
Self operator--(int)
{
Self temp(*this);
--*this;
return temp;
}
Ref operator*()
{
return _node->_t;
}
Ptr operator->()
{
return &_node->_t;
}
bool operator!=(const Self& it)
{
return _node != it._node;
}
bool operator==(const Self& it)
{
return _node == it._node;
}
};
//红黑树的反向迭代器
template<class T, class Ref, class Ptr>
struct RBTreeReverseIterator
{
typedef RBTreeNode<T> Node;
Node* _node;//要操作的节点
RBTreeReverseIterator(Node* node) :_node(node) {}
typedef RBTreeReverseIterator Self;
//++it
Self& operator--()
{
Node* cur = _node;
if (cur->_right)
{
Node* LeftMost = cur->_right;
while (LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
_node = LeftMost;
}
else
{
Node* parent = cur->_parent;
while (parent->_right == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
//it++
Self operator++(int)
{
Self temp(*this);
++*this;
return temp;
}
//--it
Self& operator++()
{
Node* cur = _node;
//end()时
if (_node->_parent->_parent == _node && _node->_col == RED)
{
_node = _node->_right;
}
else if (cur->_left)
{
Node* RightMost = cur->_left;
while (RightMost->_right)
{
RightMost = RightMost->_right;
}
_node = RightMost;
}
else
{
Node* parent = cur->_parent;
while (parent->_left == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
//it--
Self operator--(int)
{
Self temp(*this);
--*this;
return temp;
}
Ref operator*()
{
return _node->_t;
}
Ptr operator->()
{
return &_node->_t;
}
bool operator!=(const Self& it)
{
return _node != it._node;
}
bool operator==(const Self& it)
{
return _node == it._node;
}
};
//红黑树
template<class K, class T,class KeyOfT>
class RBTree
{
typedef RBTreeNode< T> Node;
void destory(Node* root)
{
if (root == nullptr)
return;
//必须后续销毁节点
destory(root->_left);
root->_left = nullptr;
destory(root->_right);
root->_right = nullptr;
delete root;
root = nullptr;
}
public:
RBTree()
{
_header = new Node(T());
}
//拷贝构造
RBTree(const RBTree& rbt)
{
_header = new Node(T());
for (const auto e : rbt)
{
insert(e);
}
}
RBTree(initializer_list<T> il)
{
_header = new Node(T());
for (const auto& e : il)
insert(e);
}
//赋值重载
RBTree& operator=(const RBTree& bst)
{
//现代写法
RBTree temp(bst);
std::swap(_header, temp._header);
return *this;
}
// 析构
~RBTree()
{
destory(_header->_parent);
delete _header;
_header = nullptr;
}
typedef RBTreeIterator<T, T&, T*> iterator;
typedef RBTreeIterator<T, const T&, const T*> const_iterator;
typedef RBTreeReverseIterator<T, T&, T*> reverse_iterator;
typedef RBTreeReverseIterator<T,const T&,const T*> const_reverse_iterator;
//迭代器
iterator begin()
{
return iterator(_header->_left);
}
const_iterator begin() const
{
return const_iterator(_header->_left);
}
iterator end()
{
return iterator(_header);
}
const_iterator end() const
{
return const_iterator(_header);
}
//反向迭代器
reverse_iterator rbegin()
{
return reverse_iterator(_header->_right);
}
const_reverse_iterator rbegin()const
{
return const_reverse_iterator(_header->_right);
}
reverse_iterator rend()
{
return reverse_iterator(_header);
}
const_reverse_iterator rend()const
{
return const_reverse_iterator(_header);
}
//此时需要注意key是set中的key,是map中pair<key,value>中的key,
// 因此我们需要取出想要的key
iterator find(const K& key) const
{
Node* cur = _header->_parent;//指向根节点
while (cur)
{
if (key < KeyOfT()(cur->_t))
{
cur = cur->_left;
}
else if (key > KeyOfT()(cur->_t))
{
cur = cur->_right;
}
else
{
return iterator(cur);
}
}
return iterator(_header);
}
pair<iterator,bool> insert(const T& t)
{
if (_header->_parent == nullptr)
{
_header->_parent = new Node(t);
_header->_parent->_col = BLACK;
_header->_parent->_parent = _header;
return { iterator(_header->_parent),true };
}
//查找结点
Node* parent = _header;
Node* cur = _header->_parent;
while (cur)
{
if (KeyOfT()(t) < KeyOfT()(cur->_t))
{
parent = cur;
cur = cur->_left;
}
else if (KeyOfT()(t) > KeyOfT()(cur->_t))
{
parent = cur;
cur = cur->_right;
}
else
{
return { iterator(cur), false };
}
}
//插入节点
cur = new Node(t);
cur->_parent = parent;
if (KeyOfT()(t) < KeyOfT()(parent->_t))
parent->_left = cur;
else
parent->_right = cur;
//保存cur,留待返回
Node* ret = cur;
//调整颜色
//情况一:parent存在且为黑,不需要调整
//情况二:parent存在且为红,需要调整
while (parent!=_header && parent->_col == RED)
{
//确定 g 和 u 节点
Node* grandfather = parent->_parent;
Node* uncle = nullptr;
if (parent == grandfather->_left)
uncle = grandfather->_right;
else
uncle = grandfather->_left;
//在情况二下又有如下情况:
//情况1:unclude存在且为红
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
//继续向上调整
cur = grandfather;
parent = cur->_parent;
}
//情况2:uncle不存在或uncle为黑
else if (!uncle || uncle->_col == BLACK)
{
//parent 是 grandfather 的左孩子
if (parent == grandfather->_left)
{
//cur 是 parent 的左孩子
if (cur == parent->_left)
{
//旋转加变色
RotateRight(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
//cur 是 parent 的右孩子
else
{
//旋转加变色
RotateLeftThenRight(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
}
//parent 是 grandfather 的右孩子
else
{
//cur 是 parent 的左孩子
if (cur == parent->_left)
{
//旋转加变色
RotateRightThenLeft(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
//cur 是 parent 的右孩子
else
{
//旋转加变色
RotateLeft(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
}
break;//调整好能退出了
}
else
{
assert(false);//逻辑错误,理论上不可能走到
}
}
_header->_parent->_col = BLACK;
_header->_left = LeftMost();
_header->_right = RightMost();
return { iterator(ret), true };
}
bool empty()
{
return _header->_parent == nullptr;
}
size_t size()
{
size_t count = 0;
auto it = begin();
while (it != end())
{
count++;
++it;
}
return count;
}
void clear()
{
destory(_header->_parent);
_header->_parent = nullptr;
}
private:
Node* LeftMost()
{
Node* MostLeftChild = _header->_parent;
while (MostLeftChild->_left)
{
MostLeftChild = MostLeftChild->_left;
}
return MostLeftChild;
}
Node* RightMost()
{
Node* MostRightChild = _header->_parent;
while (MostRightChild->_right)
{
MostRightChild = MostRightChild->_right;
}
return MostRightChild;
}
void RotateLeft(Node* parent)
{
//保存节点,后面链接
Node* parentparent = parent->_parent;
Node* sub = parent->_right;
Node* subleft = sub->_left;
//重新链接
parent->_right = subleft;
if (subleft)
subleft->_parent = parent;
sub->_left = parent;
parent->_parent = sub;
//和上面的节点链接
if (parentparent == _header)
{
//说明parent原来是根节点
_header->_parent = sub;
sub->_parent = _header;
}
else
{
if (parentparent->_left == parent)
{
//原来是上面节点的左子树
parentparent->_left = sub;
}
else
{
parentparent->_right = sub;
}
sub->_parent = parentparent;
}
}
void RotateRight(Node* parent)
{
//保存节点,后面链接
Node* parentparent = parent->_parent;
Node* sub = parent->_left;
Node* subright = sub->_right;
//重新链接
parent->_left = subright;
if (subright)
subright->_parent = parent;
sub->_right = parent;
parent->_parent = sub;
//和上面的节点链接
if (parentparent == _header)
{
//说明parent原来是根节点
_header->_parent = sub;
sub->_parent = _header;
}
else
{
if (parentparent->_left == parent)
{
//原来是上面节点的左子树
parentparent->_left = sub;
}
else
{
parentparent->_right = sub;
}
sub->_parent = parentparent;
}
}
void RotateLeftThenRight(Node* parent)
{
RotateLeft(parent->_left);
RotateRight(parent);
}
void RotateRightThenLeft(Node* parent)
{
RotateRight(parent->_right);
RotateLeft(parent);
}
private:
Node* _header;
};
2.3 set的模拟实现
#pragma once
#include"RBTree.h"
template<class K>
class set
{
typedef const K T;//和map相称
struct KeyOfT
{
const K& operator()( const T& key)
{
return key;
}
};
typedef typename RBTree<K, T, KeyOfT>::iterator iterator;
typedef typename RBTree<K, T, KeyOfT>::const_iterator const_iterator;
typedef typename RBTree<K, T, KeyOfT>::reverse_iterator reverse_iterator;
typedef typename RBTree<K, T, KeyOfT>::const_reverse_iterator const_reverse_iterator;
public:
set() = default;
set(initializer_list<T> il)
{
_rbt={ il };
}
//迭代器
iterator begin()
{
return _rbt.begin();
}
const_iterator begin()const
{
return _rbt.begin();
}
iterator end()
{
return _rbt.end();
}
const_iterator end() const
{
return _rbt.end();
}
//反向迭代器
reverse_iterator rbegin()
{
return _rbt.rbegin();
}
const_reverse_iterator rbegin()const
{
return _rbt.rbegin();
}
reverse_iterator rend()
{
return _rbt.rend();
}
const_reverse_iterator rend() const
{
return _rbt.rend();
}
bool empty()
{
return _rbt.empty();
}
size_t size()
{
return _rbt.size();
}
void clear()
{
_rbt.clear();
}
iterator find(const K& key)const
{
return _rbt.find(key);
}
pair<iterator, bool> insert(const T& t)
{
return _rbt.insert(t);
}
private:
RBTree<K, T, KeyOfT> _rbt;
};
2.4 map的模拟实现
#pragma once
#include"RBTree.h"
template<class K,class V>
class map
{
typedef pair<const K,V> T;//和map相称
struct KeyOfT
{
const K& operator()(const T& key)
{
return key.first;
}
};
typedef typename RBTree<K, T, KeyOfT>::iterator iterator;
typedef typename RBTree<K, T, KeyOfT>::const_iterator const_iterator;
typedef typename RBTree<K, T, KeyOfT>::reverse_iterator reverse_iterator;
typedef typename RBTree<K, T, KeyOfT>::const_reverse_iterator const_reverse_iterator;
public:
map() = default;
map(initializer_list<T> il)
{
_rbt = { il };
}
//迭代器
iterator begin()
{
return _rbt.begin();
}
const_iterator begin()const
{
return _rbt.begin();
}
iterator end()
{
return _rbt.end();
}
const_iterator end() const
{
return _rbt.end();
}
//反向迭代器
reverse_iterator rbegin()
{
return _rbt.rbegin();
}
const_reverse_iterator rbegin()const
{
return _rbt.rbegin();
}
reverse_iterator rend()
{
return _rbt.rend();
}
const_reverse_iterator rend() const
{
return _rbt.rend();
}
bool empty()
{
return _rbt.empty();
}
size_t size()
{
return _rbt.size();
}
void clear()
{
_rbt.clear();
}
iterator find(const K& key)const
{
return _rbt.find(key);
}
pair<iterator, bool> insert(const pair<const K,V>& kv)
{
return _rbt.insert(kv);
}
V& operator[](const K& key)
{
pair<iterator, bool> ret = insert({ key, V() });
iterator it = ret.first;
return it->second;
}
private:
RBTree < K, pair<const K, V>,KeyOfT> _rbt;//key 不能修改
};