1.底层红黑树结构
为了便于实现map和set,还需对红黑树进行一些改造:
#include<iostream>
using namespace std;
enum Color{RED, BLACK};//节点颜色
template<class T>
struct RBTreeNode {//节点定义
RBTreeNode(const T& value = T(), Color color = RED)
: _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _value(value)
, _color(color)
{}
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
T _value;
Color _color;
};
//封装迭代器类
//T-数据类型 Ref-数据引用类型 Ptr-数据指针类型
template<class T, class Ref, class Ptr>
class RBTreeIterator {
typedef RBTreeNode<T> Node;
typedef RBTreeIterator<T, Ref, Ptr> Self;//迭代器类类型
public:
RBTreeIterator(Node* pNode = nullptr)
: _pNode(pNode)
{}
Ref operator*() {
return _pNode->_value;
}
Ptr operator->() {
//return &(_pNode->_value);
return &(operator*());
}
Self& operator++() {//前置++
Increament();//加一方法
return *this;
}
Self operator++(int) {//后置++
Self temp(*this);//加一方法
Increament();
return temp;
}
Self& operator--() {//前置--
Decreament();//减一方法
return *this;
}
Self operator--(int) {//后置--
Self temp(*this);//减一方法
Decreament();
return temp;
}
bool operator==(const Self& s) const {
return _pNode == s._pNode;
}
bool operator!=(const Self& s) const {
return _pNode != s._pNode;
}
private:
void Increament() {//++
//1.右子树存在,找右子树中最左侧的节点
if (_pNode->_right) {
_pNode = _pNode->_right;
while (_pNode->_left) {
_pNode = _pNode->_left;
}
}
//2.右子树不存在,向上寻找第一个在它右侧的节点
else {
Node* parent = _pNode->_parent;
while (_pNode == parent->_right) {
_pNode = parent;
parent = _pNode->_parent;
}
//特殊情况,根节点没有右子树
if (_pNode->_right == parent) return;
_pNode = parent;
}
}
void Decreament() {//--
//特殊情况,_pNode初始再head(end)位置
if (_pNode->_parent->_parent == _pNode && _pNode->_color == RED) {
_pNode = _pNode->_right;
return;
}
//1.左子树存在,找左子树最右侧的节点
if (_pNode->_left) {
_pNode = _pNode->_left;
while (_pNode->_right) {
_pNode = _pNode->_right;
}
}
//2.左子树不存在,向上寻找第一个它左侧的节点
else {
Node* parent = _pNode->_parent;
while (_pNode == parent->_left) {
_pNode = parent;
parent = _pNode->_parent;
}
//因为--最多到begin位置,所以即使根节点没有左子树,也要更新_pNode
_pNode = parent;
}
}
private:
Node* _pNode;
};
//约定value唯一
//KofT对象获取value的Key
template<class T, class KofT>
class RBTree {
typedef RBTreeNode<T> Node;
public:
typedef RBTreeIterator<T, T&, T*> iterator;
public:
RBTree()
: _size(0)
{
_head = new Node();
_head->_left = _head;
_head->_right = _head;
}
~RBTree() {
Destroy(_head->_parent);
_size = 0;
delete _head;
_head = nullptr;
}
//迭代器
iterator begin() {
return iterator(_head->_left);
}
iterator end() {
return iterator(_head);
}
//交换
void swap(RBTree<T, KofT>& t) {
std::swap(_head, t._head);
std::swap(_size, t._size);
}
//清空
void clear() {
Destroy(_head->_parent);
_head->_left = _head;
_head->_right = _head;
_size = 0;
}
//判空
bool empty() const {
return _size == 0;
}
//插入
pair<iterator, bool> Insert(const T& value) {
Node* newNode = nullptr;
Node*& root = GetRoot();
//1.按照二叉搜索树的方式插入
if (root == nullptr) {//空树
root = new Node(value, BLACK);
newNode = root;
root->_parent = _head;
_head->_left = root;
_head->_right = root;
++_size;
return make_pair(iterator(newNode), true);
}
//查找插入位置
Node* cur = root;
Node* parent = cur->_parent;
KofT koft;
while (cur) {
parent = cur;//保存其双亲
if (koft(value) < koft(cur->_value)) {
cur = cur->_left;
}
else if (koft(value) > koft(cur->_value)) {
cur = cur->_right;
}
else {//已存在
return make_pair(iterator(cur), false);
}
}
//插入新节点
cur = new Node(value);//默认插入节点为红色
newNode = cur;
if (koft(value) < koft(parent->_value)) {
parent->_left = cur;
}
else {
parent->_right = cur;
}
cur->_parent = parent;
//2.红黑树性质约束
while (parent != _head && parent->_color == RED) {//两个红色相连违法规则
Node* grandFather = parent->_parent;
if (parent == grandFather->_left) {
Node* uncle = grandFather->_right;
//情况一:叔叔节点存在且为红
if (uncle && uncle->_color == RED) {
parent->_color = BLACK;
uncle->_color = BLACK;
grandFather->_color = RED;
//改变cur,继续向上调整
cur = grandFather;
parent = cur->_parent;
}
else {//情况二或三:叔叔节点为空,或叔叔节点存在且为黑
//因为情况三可以调整为情况二,所有先处理情况三
if (cur == parent->_right) {
//将情况三转换为情况二
RotateLeft(parent);
std::swap(parent, cur);
}
//情况二
parent->_color = BLACK;
grandFather->_color = RED;
RotateRight(grandFather);
}
}
else {//三种情况的对称情况-->解决方法相同
Node* uncle = grandFather->_left;
if (uncle && uncle->_color == RED) {//情况一
parent->_color = BLACK;
uncle->_color = BLACK;
grandFather->_color = RED;
//改变cur,继续向上调整
cur = grandFather;
parent = cur->_parent;
}
else {//情况二或三
if (cur == parent->_left) {//情况三
//调整为情况二
RotateRight(parent);
std::swap(cur, parent);
}
//情况二
parent->_color = BLACK;
grandFather->_color = RED;
RotateLeft(grandFather);
}
}
}
//注意:最后根节点可能被调整为了红色,所以需要被改回黑色
root->_color = BLACK;
//3.更新头结点左右指针域--插入元素可能改变树的最值
_head->_left = MostLeft();
_head->_right = MostRight();
++_size;
return make_pair(iterator(newNode), true);
}
//查找
iterator Find(const T& value) {
KofT koft;
Node* cur = GetRoot();
while (cur) {
if (koft(value) < koft(cur->_value)) {
cur = cur->_left;
}
else if (koft(value) > koft(cur->_value)) {
cur = cur->_right;
}
else {
return iterator(cur);
}
}
return end();
}
//检测是否是红黑树
bool IsRBTree() {
Node* root = GetRoot();
if (root == nullptr) return true;
if (root->_color == RED) {
//检测性质2
std::cout << "FALSE: 根节点为红色!" << std::endl;
return false;
}
int blackCount = 0;
Node* cur = root;
while (cur) {//统计一条路径黑色节点个数
if (cur->_color == BLACK) ++blackCount;
cur = cur->_left;
}
return _IsRBTree(root, blackCount, 0);
}
//中序遍历
void InOrder() {
_InOrder(GetRoot());
std::cout << std::endl;
}
//获取最值
int GetMax() {
return MostRight()->_value;
}
int GetMin() {
return MostLeft()->_value;
}
private:
//获取根节点
Node*& GetRoot() {
return _head->_parent;
}
//获取树的最值节点
Node* MostLeft() {//最左侧节点
Node*& root = GetRoot();
if (root == nullptr) return _head;
Node* cur = root;
while (cur->_left) {
cur = cur->_left;
}
return cur;
}
Node* MostRight() {//最右侧节点
Node*& root = GetRoot();
if (root == nullptr) return _head;
Node* cur = root;
while (cur->_right) {
cur = cur->_right;
}
return cur;
}
//左单旋
void RotateLeft(Node* parent) {
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL) {//注意subrl可能为空
subRL->_parent = parent;
}
subR->_left = parent;
//跟新parent和subR的双亲节点
//先保存好parent原先的双亲节点
Node* pparent = parent->_parent;
parent->_parent = subR;
subR->_parent = pparent;
//处理上层节点
if (pparent == _head) {//已经更新到根节点
_head->_parent = subR;
}
else {
if (parent == pparent->_left) {
pparent->_left = subR;
}
else {
pparent->_right = subR;
}
}
}
//右单旋
void RotateRight(Node* parent) {
//其思想与左单旋相同
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR) {
subLR->_parent = parent;
}
subL->_right = parent;
Node* pparent = parent->_parent;
parent->_parent = subL;
subL->_parent = pparent;
if (pparent == _head) {
_head->_parent = subL;
}
else {
if (parent == pparent->_left) {
pparent->_left = subL;
}
else {
pparent->_right = subL;
}
}
}
//检测是否满足红黑树特性
bool _IsRBTree(Node* root, const int blackNum, int count) {
if (root == nullptr) return true;
if (root->_color == BLACK) ++count;//统计路径内的黑色节点
//检测是否满足性质3
if (root->_parent != _head && root->_color == RED && root->_parent->_color == RED) {
std::cout << "FALSE: 存在两个相连的红色节点!" << std::endl;
return false;
}
if (root->_left == nullptr && root->_right == nullptr) {
//是叶子节点,此路径统计结束
return count == blackNum;//检测性质4
}
return _IsRBTree(root->_left, blackNum, count) && _IsRBTree(root->_right, blackNum, count);
}
//中序遍历
void _InOrder(Node*& root) {
if (root == nullptr) return;
_InOrder(root->_left);
std::cout << root->_value << " ";
_InOrder(root->_right);
}
//销毁
void Destroy(Node* root) {
if (root == nullptr) return;
Destroy(root->_left);
Destroy(root->_right);
delete root;
root = nullptr;
}
private:
Node* _head;
public:
size_t _size;
};
2.map封装
#include "RBTree.hpp"
namespace MyMap {
template<class Key, class T>
class map {
typedef pair<Key, T> ValueType;
struct KofT {//作用:将value的key提取出来
const Key& operator() (const ValueType& value) {
return value.first;
}
};
typedef RBTree<ValueType, KofT> Tree;
/*typedef Tree::iterator iterator;
上面这种方式,编译器无法确定iterator是Tree中的类型。
因为静态成员变量也是通过类名::静态成员变量的方式进行访问
解决方法:用typename显示告诉编译器它是类型*/
typedef typename Tree::iterator iterator;
public:
map()
: _rbTree()
{}
//迭代器
iterator begin() {
return _rbTree.begin();
}
iterator end() {
return _rbTree.end();
}
//判空
bool empty() const {
return _rbTree.empty();
}
//容量
size_t size() const {
return _rbTree._size;
}
void clear() {
_rbTree.clear();
}
//操作
pair<iterator, bool> insert(const ValueType& value) {
return _rbTree.Insert(value);
}
T& operator[](const Key& key) {
return (*((insert(make_pair(key, T()))).first)).second;
}
void swap(map<Key, T>& m) {
_rbTree.swap(m._rbTree);
}
iterator find(const Key& key) {
return _rbTree.Find(make_pair(key, T()));
}
private:
Tree _rbTree;
};
}
3.set封装
#include "RBTree.hpp"
namespace MySet {
template<class T>
class set {
typedef T ValueType;
struct KofT {
const T& operator() (const ValueType& value) {
return value;
}
};
typedef RBTree<ValueType, KofT> Tree;
typedef typename Tree::iterator iterator;
public:
set()
: _rbTree()
{}
//迭代器
iterator begin() {
return _rbTree.begin();
}
iterator end() {
return _rbTree.end();
}
//判空
bool empty() const {
return _rbTree.empty();
}
//容量
size_t size() const {
return _rbTree._size;
}
void clear() {
_rbTree.clear();
}
//操作
pair<iterator, bool> insert(const ValueType& value) {
return _rbTree.Insert(value);
}
void swap(set<ValueType>& m) {
_rbTree.swap(m._rbTree);
}
iterator find(const T& key) {
return _rbTree.Find(key);
}
private:
Tree _rbTree;
};
}