个人主页:仍有未知等待探索-CSDN博客
专题分栏:C++
一、简介
map和set都是关联性容器,底层都是用红黑树写的。
**特点:**存的Key值都是唯一的,不重复。
map存的是键值对(Key---Value)。
set存的是键值(Key)。
二、map/set的模拟实现
map.h
cpp
#pragma once
#include <iostream>
#include "RBTree.h"
using namespace std;
template<class Key, class Value>
class map
{
struct MapKeyOfT
{
const Key& operator()(const pair<Key, Value>& e)
{
return e.first;
}
};
public:
typedef pair<Key, Value> PKV;
typedef _RBTree_iterator<PKV, PKV*, PKV&> iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
bool insert(const pair<Key, Value>& e)
{
return _t.insert(e);
}
void inorder()
{
_t.inorder();
}
private:
RBTree<Key, pair<Key, Value>, MapKeyOfT> _t;
};
set.h
cpp
#pragma once
#include "RBTree.h"
template<class Key>
class set
{
struct SetKeyOfT
{
const Key& operator()(const Key& e)
{
return e;
}
};
public :
typedef _RBTree_iterator<Key, Key*, Key&> iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
bool insert(const Key& e)
{
return _t.insert(e);
}
void inorder()
{
_t.inorder();
}
private:
RBTree<Key, Key, SetKeyOfT> _t;
};
RBTree.h
cpp
#pragma once
#include<iostream>
using namespace std;
enum color
{
Red,
Black
};
template <class ValueTpye>
struct RBTreeNode
{
RBTreeNode(const ValueTpye& e = ValueTpye())
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_col(Red)
,_val(e)
{}
struct RBTreeNode<ValueTpye>* _left;
struct RBTreeNode<ValueTpye>* _right;
struct RBTreeNode<ValueTpye>* _parent;
int _col;
ValueTpye _val;
};
template<class ValueType, class Ptr, class Ref>
class _RBTree_iterator
{
typedef RBTreeNode<ValueType> node;
typedef _RBTree_iterator<ValueType, Ptr, Ref> iterator;
public:
_RBTree_iterator(node* e)
:_node(e)
{}
Ptr operator->()
{
return &_node->_val;
}
Ref operator*()
{
return _node->_val;
}
bool operator!=(iterator it)
{
return _node != it._node;
}
iterator& operator++()
{
if (_node->_right)
{
node* left = _node->_right;
while (left->_left)
{
left = left->_left;
}
_node = left;
}
else
{
node* cur = _node;
node* p = cur->_parent;
while (p && cur == p->_right)
{
cur = p;
p = p->_parent;
}
_node = p;
}
return *this;
}
private:
node* _node;
};
template <class Key, class ValueType, class KeyOfT>
class RBTree
{
public:
typedef RBTreeNode<ValueType> node;
typedef _RBTree_iterator<ValueType, ValueType*, ValueType&> iterator;
KeyOfT kot;
RBTree()
:_root(nullptr)
{}
iterator begin()
{
node* cur = _root;
while (cur && cur->_left)
{
cur = cur->_left;
}
return iterator(cur);
}
iterator end()
{
return iterator(nullptr);
}
node* find(const Key& e)
{
node* cur = _root;
while (cur)
{
if (kot(cur->_val).first > e)
{
cur = cur->_left;
}
else if (kot(cur->_val).first < e)
{
cur = cur->_right;
}
else
{
return cur;
}
}
return nullptr;
}
bool insert(const ValueType& e)
{
// 根据二叉搜索树插入的方式进行插入
node* cur = _root;
node* parent = cur;
while (cur)
{
parent = cur;
if (kot(cur->_val) > kot(e))
{
cur = cur->_left;
}
else if (kot(cur->_val) < kot(e))
{
cur = cur->_right;
}
else
{
return false;
}
}
cur = new node(e);
if (parent == nullptr)
{
_root = cur;
}
else
{
if (kot(parent->_val) > kot(cur->_val))
{
parent->_left = cur;
}
else
{
parent->_right = cur;
}
cur->_parent = parent;
}
// 更新,对于不同的情况,进行不同的调整
// parent 为黑、不存在,结束
node* p = parent;
while (p && p->_col == Red)
{
node* g = p->_parent;
if (g->_left == p)
{
node* u = g->_right;
// 叔叔存在且为红
if (u && u->_col == Red)
{
p->_col = u->_col = Black;
g->_col = Red;
// 继续往上处理
cur = g;
p = cur->_parent;
}
// 叔叔不存在且为黑
else
{
// g
// p u
// c
if (cur == p->_left)
{
// 右单旋
RotateR(g);
// 变色
g->_col = Red;
p->_col = Black;
}
// g
// p u
// c
else
{
// 左右双旋
RotateL(p);
RotateR(g);
// 变色
cur->_col = Black;
g->_col = Red;
}
// 叔叔不存在或者存在且为黑调整完,就不需要继续进行调整了
break;
}
}
else
{
node* u = g->_left;
if (u && u->_col == Red)
{
p->_col = u->_col = Black;
g->_col = Red;
// 继续往上处理
cur = g;
p = cur->_parent;
}
else
{
// g
// u p
// c
if (cur == p->_right)
{
// 左单旋
RotateL(g);
// 变色
g->_col = Red;
p->_col = Black;
}
// g
// u p
// c
else
{
// 左右双旋
RotateR(p);
RotateL(g);
// 变色
cur->_col = Black;
g->_col = Red;
}
// 叔叔不存在或者存在且为黑调整完,就不需要继续进行调整了
break;
}
}
}
_root->_col = Black;
return true;
}
void inorder()
{
_inorder(_root);
}
private:
void _inorder(node* root)
{
if (root == nullptr) return;
_inorder(root->_left);
cout << kot(root->_val) << " ";
_inorder(root->_right);
}
void RotateR(node* parent)
{
node* subl = parent->_left;
node* sublr = subl->_right;
node* grandfather = parent->_parent;
parent->_left = sublr;
if (sublr)
{
sublr->_parent = parent;
}
subl->_right = parent;
parent->_parent = subl;
subl ->_parent = grandfather;
if (_root == parent)
{
if (grandfather->_left == parent)
{
grandfather->_left = subl;
}
else
{
grandfather->_right = subl;
}
}
else
{
_root = subl;
}
}
void RotateL(node* parent)
{
node* subr = parent->_right;
node* subrl = subr->_left;
node* grandfather = parent->_parent;
parent->_right = subrl;
if (subrl)
{
subrl->_parent = parent;
}
subr->_left = parent;
parent->_parent = subr;
subr ->_parent = grandfather;
if (_root != parent)
{
if (grandfather->_left == parent)
{
grandfather->_left = subr;
}
else
{
grandfather->_right = subr;
}
}
else
{
_root = subr;
}
}
private:
node* _root;
};
main.cpp(测试)
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "map.h"
#include "set.h"
//#include <map>
//#include <set>
#include <iostream>
using namespace std;
void test1()
{
int a[] = {5, 3, 7, 3, 7, 8, 4, 2, 9, 10};
map<int, int> m;
for (int e : a)
{
m.insert(make_pair(e, e));
}
m.inorder();
}
void test2()
{
int a[] = {5, 3, 7, 3, 7, 8, 4, 2, 9, 10};
set<int> s;
for (int e : a)
{
s.insert(e);
}
s.inorder();
}
void test3()
{
int a[] = {5, 3, 7, 3, 7, 8, 4, 2, 9, 10};
set<int> s;
for (int e : a)
{
s.insert(e);
}
auto it = s.begin();
while (it != s.end())
{
cout << *it << endl;
++ it;
}
}
void test4()
{
pair<int, int> a[] = {{5, 5}, {3, 3}, {7, 7}, {3, 3}, {7, 7}, {8, 8}, {4, 4}, {2, 2}, {9, 9}, {10, 10}};
set<pair<int, int>> s;
for (auto e : a)
{
s.insert(e);
}
auto it = s.begin();
while (it != s.end())
{
cout << (*it).first << " " << (*it).second << endl;
++ it;
}
}
int main()
{
test1();
return 0;
}