C++ ──── set和map的模拟实现
目录
1. 因为set和map底层都是红黑树,因此直接改造红黑树即可
3.红黑树实现迭代器(++ -- *() ->() != ==)
红黑树的迭代器
迭代器的好处是可以方便遍历,是数据结构的底层实现与用户透明。如果想要给红黑树增加迭代器,需要考虑以前问题: begin()与end() STL明确规定,begin()与end()代表的是一段前闭后开的区间,而对红黑树进行中序遍历后, 可以得到一个有序的序列,
因此:begin()可以放在红黑树中最小节点(即最左侧节点)的位置,end()放在最大节点(最右侧节点)的下一个位置,关键是最大节点的下一个位置在哪块?
能否给成nullptr呢?
答案是也可以,但是对end()位置的迭代器进行 - - 操作,必须要能找最后一个元素,最好的方式是将end()放在头结点的位置:
1. 因为set和map底层都是红黑树,因此直接改造红黑树即可
set 存Key ,而map存的是pair<key ,value >,因此将红黑树的节点存储改为T,传什么就存储什么
2. 红黑树的三个模版参数
因为红黑树中的Find 和Erase 需要传key来查找 和删除
Insert 和 Node 需要插入T
所以要传两个模版参数K 和 T
但是在函数insert中map存储的pair 和set存储的key 红黑树并不知道是哪个进而无法比较大小来确定位置,所以还要传一个仿函数来取key ,第三个模版参数keyOfT
3.红黑树实现迭代器(++ -- *() ->() != ==)
在红黑树里实现begin() 和end()
4.封装set
#pragma once
#include"RBTree.h"
namespace BMH
{
template<class K>
class set
{
struct SetKeyOfT
{
const K& operator()(const K& key)
{
return key;
}
};
public:
typedef typename RBTree<K, const K, SetKeyOfT>::Iterator iterator;//set迭代器不支持修改,因为红黑底层是搜索树
typedef typename RBTree<K, const K, SetKeyOfT>::ConstIterator const_iterator;
iterator begin()
{
return _t.Begin();
}
iterator end()
{
return _t.End();
}
const_iterator begin() const
{
return _t.Begin();
}
const_iterator end() const
{
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, const K, SetKeyOfT> _t;
};
void Print(const set<int>& s)
{
set<int>::const_iterator it = s.end();
while (it != s.begin())
{
--it;
//*it += 2; set不能修改
cout << *it << " ";
}
cout << endl;
}
void test_set()
{
set<int> s;
int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
for (auto e : a)
{
s.insert(e);
}
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
set<int>::iterator it = s.end();
while (it != s.begin())
{
--it;
cout << *it << " ";
}
cout << endl;
it = s.begin();
//*it += 10;
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
Print(s);
}
}
map的底层结构就是红黑树,因此在map中直接封装一棵红黑树,然后将其接口包装下即可
5.封装map
#pragma once
#include"RBTree.h"
namespace BMH
{
template<class K ,class V>
class map
{
struct MapKeyOfT
{
const K& operator()(const pair<K,V>& KV)
{
return KV.first;
}
};
public:
typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::Iterator iterator;//因为map的key不能改,V可以改 所以key加上const
typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::ConstIterator const_iterator;//因为map的key不能改,V可以改 所以key加上const
iterator begin()
{
return _t.Begin();
}
iterator end()
{
return _t.End();
}
const_iterator begin() const
{
return _t.Begin();
}
const_iterator end() const
{
return _t.End();
}
iterator find(const K& key)
{
return _t.Find(key);
}
pair<iterator, bool> insert(const pair<K, V>& KV)
{
return _t.Insert(KV);
}
V& operator[](const K& key)
{
pair<iterator, bool> ret = insert(make_pair(key, V()));
return (ret.first)->second;
}
private:
RBTree<K, pair<const K, V>, MapKeyOfT> _t;//因为map的key不能改,V可以改 所以key加上const
};
void test_map()
{
map<string, string> dict;
dict.insert({ "sort", "排序" });
dict.insert({ "left", "左边" });
dict.insert({ "right", "右边" });
dict["left"] = "左边,剩余";
dict["insert"] = "插入";
dict["string"];
map<string, string>::iterator it = dict.begin();
while (it != dict.end())
{
// 不能修改first,可以修改second
//it->first += 'x';
it->second += 'x';
cout << it->first << ":" << it->second << endl;
++it;
}
cout << endl;
}
}
红黑树
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
enum Colour
{
RED,
BLACK
};
template <class T>
struct RBTNode
{
T _data;
RBTNode* _left;
RBTNode* _right;
RBTNode* _parent;
Colour _col;
RBTNode(const T& data)
:_data(data)
, _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
{}
};
template<class T, class Ref ,class Ptr>//增加Ref 和Ptr 为了使其也能实现const_iterator
struct RBTIterator
{
typedef RBTNode<T> Node;
typedef RBTIterator<T, Ref,Ptr> Self;
Node* _node;
Node* _root;
RBTIterator(Node* node, Node* root)
:_node(node)
,_root(root)
{}
Self& operator++()
{
if (_node->_right)//右不为空,下一个为右子树的最左节点
{
Node* LeftMost = _node->_right;
while (LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
_node = LeftMost;
}
else
{
//右边为空,向上找有左孩子的祖先
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
Self& operator--()
{
if (_node == nullptr) // end()
{
// --end(),特殊处理,走到中序最后一个节点,整棵树的最右节点
Node* rightMost = _root;
while (rightMost && rightMost->_right)
{
rightMost = rightMost->_right;
}
_node = rightMost;
}
else if (_node->_left)//存在左边,找左子树最右边
{
Node* Mostright = _node->_left;
while(Mostright->_right)
{
Mostright = Mostright->_right;
}
_node = Mostright;
}
else//不存在左边,找有右孩子的祖先
{
Node* cur = _node;
Node* parent = _node->_parent;
while (parent && parent->_left == cur)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(_node->_data);
}
bool operator!=(const Self& s)
{
return _node != s._node;
}
bool operator==(const Self& s)
{
return _node == s._node;
}
};
template<class K, class T, class KeyOfT>
class RBTree
{
typedef RBTNode<T> Node;
public:
typedef RBTIterator<T, T&, T*> Iterator;
typedef RBTIterator<T, const T&, const T*> ConstIterator;
Iterator Begin()
{
Node* LeftMost = _root;
while (LeftMost && LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
return Iterator(LeftMost, _root);
}
Iterator End()
{
return Iterator(nullptr ,_root);
}
ConstIterator Begin()const
{
Node* LeftMost = _root;
while (LeftMost && LeftMost->_left)
{
LeftMost = LeftMost->_left;
}
return ConstIterator(LeftMost, _root);
}
ConstIterator End() const
{
return ConstIterator(nullptr, _root);
}
RBTree()
:_root(nullptr)
{}
RBTree(const RBTree<K, T, KeyOfT>& t)
{
_root = Copy(t._root);
}
~RBTree()
{
Destroy(_root);
_root = nullptr;
}
void Inorder()
{
_Inorder(_root);
}
Iterator Find(const K& key)
{
//从根开始找
Node* cur = _root;
KeyOfT KOT;
while (cur)
{
if (KOT(cur) > key)
{
cur = cur->_left;
}
else if (KOT(cur) < key)
{
cur = cur->_right;
}
else
{
return Iterator(cur,_root);
}
}
return End();
}
pair<Iterator, bool> Insert(const T& data)
{
//第一个结点
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return std::make_pair(Iterator(_root ,_root), true);
}
//从根开始找,看看有没有,没有再插入
Node* cur = _root;
Node* parent = nullptr;//parent是要插入位置的父亲
KeyOfT KOT;
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 std::make_pair(Iterator(cur, _root), false);
}
}
Node* newNode = new Node(data);
//新增节点,颜色给红色
newNode->_col = RED;
if (KOT(parent->_data) < KOT(data))
{
parent->_right = newNode;
}
else
{
parent->_left = newNode;
}
newNode->_parent = parent;
cur = newNode;
//父亲为黑色直接结束
//父亲节点为红色(出现双红情况),进行处理
while (parent && parent->_col == RED)
{
Node* grandfather = parent->_parent;
// g
// p
//new
if (parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
if (uncle && uncle->_col == RED)// u存在且为红 -》变色再继续往上处理
{
// g
// p u
//new
parent->_col = BLACK;
uncle->_col = BLACK;
grandfather->_col = RED;
//向上处理
cur = grandfather;
parent = cur->_parent;
}
else// u不存在或存在且为黑
{
// g g
// p p u
//curcur
if (cur == parent->_left)//右单旋
{
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else//双旋
{
// g g
// p p u
//curcur
RotateL(parent);
RotateR(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else
{
// g
//up
// new
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
// g
// u p
//new
parent->_col = BLACK;
uncle->_col = BLACK;
grandfather->_col = RED;
//向上处理
cur = grandfather;
parent = cur->_parent;
}
else
{
// g g
// p u p
//cur cur
if (cur == parent->_right)//单旋
{
RotateL(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
// g g
// p u p
//cur cur
RotateR(parent);
RotateL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return std::make_pair(Iterator(newNode, _root), true);
}
bool IsBalance()
{
if (_root == nullptr)
return true;
if (_root->_col == RED)
{
return false;
}
// 参考值
int refNum = 0;
Node* cur = _root;
while (cur)
{
if (cur->_col == BLACK)
{
++refNum;
}
cur = cur->_left;
}
return Check(_root, 0, refNum);
}
private:
bool Check(Node* root, int blackNum, const int refNum)
{
KeyOfT KOT;
if (root == nullptr)
{
//cout << blackNum << endl;
if (refNum != blackNum)
{
cout << "存在黑色节点的数量不相等的路径" << endl;
return false;
}
return true;
}
if (root->_col == RED && root->_parent->_col == RED)
{
cout << KOT(root->_data) << "存在连续的红色节点" << endl;
return false;
}
if (root->_col == BLACK)
{
blackNum++;
}
return Check(root->_left, blackNum, refNum)
&& Check(root->_right, blackNum, refNum);
}
int _Height(Node* Root)
{
if (Root == nullptr)
return 0;
int leftHeight = _Height(Root->_left);
int rightHeight = _Height(Root->_right);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
void RotateR(Node* parent)
{
if (parent == nullptr)
return;
Node* SubL = parent->_left;
Node* SubLR = SubL->_right;
Node* parent2 = parent->_parent;
parent->_left = SubLR;
if (SubLR)
{
SubLR->_parent = parent;
}
SubL->_right = parent;
parent->_parent = SubL;
if (parent2)
{
if (parent2->_left == parent)
{
parent2->_left = SubL;
}
else
{
parent2->_right = SubL;
}
SubL->_parent = parent2;
}
else
{
_root = SubL;
SubL->_parent = nullptr;//容易忘
}
}
void RotateL(Node* parent)
{
if (parent == nullptr)
return;
Node* SubR = parent->_right;
Node* SubRL = SubR->_left;
Node* parent2 = parent->_parent;
parent->_parent = SubR;
SubR->_left = parent;
parent->_right = SubRL;
if (SubRL)
SubRL->_parent = parent;
if (parent2)
{
if (parent2->_left == parent)
{
parent2->_left = SubR;
}
else
{
parent2->_right = SubR;
}
SubR->_parent = parent2;
}
else
{
_root = SubR;
_root->_parent = nullptr;
}
}
Node* Copy(Node* root)
{
if (root == nullptr)
return nullptr;
//前序创建树
Node* newRoot = new Node(root->_data);
newRoot->_left = Copy(root->_left);
newRoot->_right = Copy(root->_right);
return newRoot;
}
void Destroy(Node* root)
{
if (root == nullptr)
return;
//后序毁树
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
void _Inorder(Node* root)
{
if (root == nullptr)
{
return;
}
KeyOfT KOT;
_Inorder(root->_left);
cout << KOT(root->_data) << endl;
_Inorder(root->_right);
}
private:
Node* _root;
};
//void TestRBTree1()
//{
//RBTree<int, int> t;
////int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
//int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14,18,26,24,31 };
//for (auto e : a)
//{
///*if (e == 9)
//{
//int i = 0;
//}*/
//
//t.Insert({ e, e });
//
////cout << e << "->" << t.IsBalanceTree() << endl;
//}
//
//t.Inorder();
//cout << t.IsBalance() << endl;
//}
原文地址:https://blog.csdn.net/m0_73751295/article/details/143837377
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!