1.Map和Set的简单介绍
Map和set没有多大区别,它俩都是键值对容器,即该结构中一般只包含两个成员key,value,key代表键值,value表示与key对应的信息。并且这两个容器为树型结构的关联式容器,这两种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。
Set的介绍:
- set是按照一定次序存储元素的容器。
- 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。
- set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
- 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
- set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
- set在底层是用二叉搜索树(红黑树)实现的。
注意:
- 与map/multimap不同,map/multimap中存储的是真正的键值对
,set中只放value,但在底层实际存放的是由 构成的键值对。 - set中插入元素时,只需要插入value即可,不需要构造键值对。
- set中的元素不可以重复(因此可以使用set进行去重)。
- 使用set的迭代器遍历set中的元素,可以得到有序序列
- set中的元素默认按照小于来比较
- set中查找某个元素,时间复杂度为:$log_2 n$
- set中的元素不允许修改
- set中的底层使用二叉搜索树(红黑树)来实现
Map的介绍:
- map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
- 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型
- value_type绑定在一起,为其取别名称为pair:
- typedef pair
value_type; - 在内部,map中的元素总是按照键值key进行比较排序的。
- map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
- map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
- map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。
2.Map和Set的实现
由于Map和Set的底层都为红黑树,所以Map和Set的实现通过对红黑树的封装来实现,Set为一个参数,Map为两个参数,所以通过改变模板来实现Map和Set的同时封装。
Set的简单封装:
namespace sss
{
template
class Set
{
struct SetKeyofT
{
const K& operator()(const K& date)
{
return date;
}
};
public:
typedef typename RedBlackTree::iterator iterator;
iterator begin()
{
return _S.begin();
}
iterator end()
{
return _S.end();
}
pair Insert(const K& date)
{
return _S.insert(date);
}
private:
RedBlackTree _S;
};
//测试用例
/*void text_set()
{
string str[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
Set hash;
for (auto sh : str)
{
hash.Insert(sh);
}
auto it = hash.begin();
while (it != hash.end())
{
cout << *it << endl;
++it;
}
}*/
}
Map的简单封装
namespace sss
{
template
class Map
{
public:
struct MapKeyofT
{
const K& operator()(const pair& date)
{
return date.first;
}
};
typedef typename RedBlackTree, MapKeyofT>::iterator iterator;
//t//ypedef RedBlackTree, MapKeyofT> RedBlackTree;
iterator begin()
{
return _T.begin();
}
iterator end()
{
return _T.end();
}
pair Insert(const pair& date)
{
return _T.insert(date);
}
V& operator[](const K& key)
{
pair ret = Insert(make_pair(key, V()));
return ret.first->second;
}
private:
RedBlackTree, MapKeyofT> _T;
};
//测试用例
//void text_map()
//{
// Map hash1;
// hash1.Insert(make_pair(1,1));
// cout< hash2;
// string str[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
// for (auto sh:str)
// {
// hash2[sh]++;
// }
// Map::iterator it = hash2.begin();
// while (it != hash2.end())
// {
// cout << it->first << ":" << it->second << endl;
// ++it;
// }
// for (auto& kv : hash2)
// {
// cout << kv.first << ":" << kv.second << endl;
// }
// //hash1 = hash2;
//
//}
}
底层实现:
namespace sss
{
enum Color
{
red,
black
};
template
struct RedBlackTreeNode
{
RedBlackTreeNode* _left;
RedBlackTreeNode* _right;
RedBlackTreeNode* _parent;
//pair _date;
T _date;
Color _col;
RedBlackTreeNode(const T& date=T())
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_date(date)
//, _col(black)
{}
};
template
struct __RBTreeIterator
{
typedef RedBlackTreeNode Node;
typedef __RBTreeIterator Self;
Node* _node;
__RBTreeIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_date;
}
Ptr operator->()
{
return &_node->_date;
}
bool operator!=(const Self& _t)
{
return _node != _t._node;
}
bool operator==(const Self& _t)
{
return _node == _t._node;
}
Self* operator++()
{
if (_node->_right)
{
Node* cur = _node;
cur = cur->_right;
while (cur->_left)
{
cur = cur->_left;
}
_node=cur;
}
else
{
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node=parent;
}
return this;
}
Self* operator--()
{
if (_node->_left)
{
Node* cur = _node;
cur = cur->_left;
while (cur->_right)
{
cur = cur->_right;
}
_node=cur;
}
else
{
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->left)
{
parent = parent->_parent;
cur = parent;
}
_node= parent;
}
return this;
}
};
template
class RedBlackTree
{
typedef RedBlackTreeNode Node;
public:
typedef __RBTreeIterator iterator;
iterator begin()
{
Node* left = _root;
while (left && left->_left)
{
left = left->_left;
}
return iterator(left);
}
iterator end()
{
return iterator(nullptr);
}
//插入
pair insert(const T& date)
{
KeyofT _com;
if (_root == nullptr)
{
_root = new Node(date);
_root->_col = black;
return make_pair(iterator(_root), true);
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (_com(cur->_date)< _com(date))
{
parent = cur;
cur = cur->_right;
}
else if (_com(cur->_date) > _com(date))
{
parent = cur;
cur = cur->_left;
}
else
{
return make_pair(iterator(cur), false);
}
}
cur = new Node(date);
cur->_col = red;
if (_com(parent->_date) < _com(date))
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
cur->_parent = parent;
//Node* uncle=parent->_parent->
while(parent && parent->_col == red)
{
Node* grandfater = parent->_parent;
assert(grandfater);
assert(grandfater->_col==black);
if (parent == grandfater->_left)
{
Node* uncle = grandfater->_right;
// 情况一 : uncle存在且为红,变色+继续往上处理
if (uncle && uncle->_col == red)
{
parent->_col = uncle->_col = black;
grandfater->_col = red;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}// 情况二+三:uncle不存在 + 存在且为黑
else
{
// 情况二:右单旋+变色
// g
// p u
// c
if (cur == parent->_left)
{
RotateR(grandfater);
parent->_col = black;
grandfater->_col = red;
}
else
{
// 情况三:左右单旋+变色
// g
// p u
// c
RotateL(parent);
RotateR(grandfater);
cur->_col = black;
grandfater->_col = red;
}
break;
}
}
else
{
Node* uncle = grandfater->_left;
// 情况一
if (uncle && uncle->_col == red)
{
parent->_col = uncle->_col = black;
grandfater->_col = red;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}
else
{
// 情况二:左单旋+变色
// g
// u p
// c
if (cur == parent->_right)
{
RotateL(grandfater);
parent->_col = black;
grandfater->_col = red;
}
else
{
// 情况三:右左单旋+变色
// g
// u p
// c
RotateR(parent);
RotateL(grandfater);
cur->_col = black;
grandfater->_col = red;
}
break;
}
}
}
_root->_col = black;
return make_pair(iterator(cur), true);
}
void Inorder()
{
_Inorder(_root);
}
private:
//右旋
void RotateR(Node* parent)
{
Node* subl = parent->_left;
Node* sublr = subl->_right;
Node* prev = parent->_parent;
parent->_left = sublr;
if (sublr)
sublr->_parent = parent;
parent->_parent = subl;
subl->_right = parent;
if (_root == parent)
{
_root = subl;
subl->_parent = nullptr;
}
else
{
if (prev->_left == parent)
{
subl->_parent = prev;
prev->_left = subl;
}
else
{
subl->_parent = prev;
prev->_right = subl;
}
}
}
//左旋
void RotateL(Node* parent)
{
Node* subr = parent->_right;
Node* subrl = subr->_left;
Node* prev = parent->_parent;
parent->_right = subrl;
if (subrl)
subrl->_parent = parent;
subr->_left = parent;
parent->_parent = subr;
if (_root == parent)
{
_root = subr;
subr->_parent = nullptr;
}
else
{
if (prev->_left == parent)
{
subr->_parent = prev;
prev->_left = subr;
}
else
{
subr->_parent = prev;
prev->_right = subr;
}
}
}
//遍历
void _Inorder(Node* _root)
{
if (_root == nullptr)
return;
_Inorder(_root->_left);
cout << _root->_date.first << " " << _root->_date.second << endl;
_Inorder(_root->_right);
}
private:
Node* _root = nullptr;
};
}
完整代码:
//在不同平台下需加不同头文件
#pragma once
using namespace std;
#include
#include
#include "RedBlackTree.h"
#include
namespace sss
{
template
class Set
{
struct SetKeyofT
{
const K& operator()(const K& date)
{
return date;
}
};
public:
typedef typename RedBlackTree::iterator iterator;
iterator begin()
{
return _S.begin();
}
iterator end()
{
return _S.end();
}
pair Insert(const K& date)
{
return _S.insert(date);
}
private:
RedBlackTree _S;
};
//测试用例
/*void text_set()
{
string str[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
Set hash;
for (auto sh : str)
{
hash.Insert(sh);
}
auto it = hash.begin();
while (it != hash.end())
{
cout << *it << endl;
++it;
}
}*/
}
namespace sss
{
template
class Map
{
public:
struct MapKeyofT
{
const K& operator()(const pair& date)
{
return date.first;
}
};
typedef typename RedBlackTree, MapKeyofT>::iterator iterator;
//t//ypedef RedBlackTree, MapKeyofT> RedBlackTree;
iterator begin()
{
return _T.begin();
}
iterator end()
{
return _T.end();
}
pair Insert(const pair& date)
{
return _T.insert(date);
}
V& operator[](const K& key)
{
pair ret = Insert(make_pair(key, V()));
return ret.first->second;
}
private:
RedBlackTree, MapKeyofT> _T;
};
//测试用例
//void text_map()
//{
// Map hash1;
// hash1.Insert(make_pair(1,1));
// cout< hash2;
// string str[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
// for (auto sh:str)
// {
// hash2[sh]++;
// }
// Map::iterator it = hash2.begin();
// while (it != hash2.end())
// {
// cout << it->first << ":" << it->second << endl;
// ++it;
// }
// for (auto& kv : hash2)
// {
// cout << kv.first << ":" << kv.second << endl;
// }
// //hash1 = hash2;
//
//}
}
namespace sss
{
enum Color
{
red,
black
};
template
struct RedBlackTreeNode
{
RedBlackTreeNode* _left;
RedBlackTreeNode* _right;
RedBlackTreeNode* _parent;
//pair _date;
T _date;
Color _col;
RedBlackTreeNode(const T& date=T())
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_date(date)
//, _col(black)
{}
};
template
struct __RBTreeIterator
{
typedef RedBlackTreeNode Node;
typedef __RBTreeIterator Self;
Node* _node;
__RBTreeIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_date;
}
Ptr operator->()
{
return &_node->_date;
}
bool operator!=(const Self& _t)
{
return _node != _t._node;
}
bool operator==(const Self& _t)
{
return _node == _t._node;
}
Self* operator++()
{
if (_node->_right)
{
Node* cur = _node;
cur = cur->_right;
while (cur->_left)
{
cur = cur->_left;
}
_node=cur;
}
else
{
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node=parent;
}
return this;
}
Self* operator--()
{
if (_node->_left)
{
Node* cur = _node;
cur = cur->_left;
while (cur->_right)
{
cur = cur->_right;
}
_node=cur;
}
else
{
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->left)
{
parent = parent->_parent;
cur = parent;
}
_node= parent;
}
return this;
}
};
template
class RedBlackTree
{
typedef RedBlackTreeNode Node;
public:
typedef __RBTreeIterator iterator;
iterator begin()
{
Node* left = _root;
while (left && left->_left)
{
left = left->_left;
}
return iterator(left);
}
iterator end()
{
return iterator(nullptr);
}
//插入
pair insert(const T& date)
{
KeyofT _com;
if (_root == nullptr)
{
_root = new Node(date);
_root->_col = black;
return make_pair(iterator(_root), true);
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (_com(cur->_date)< _com(date))
{
parent = cur;
cur = cur->_right;
}
else if (_com(cur->_date) > _com(date))
{
parent = cur;
cur = cur->_left;
}
else
{
return make_pair(iterator(cur), false);
}
}
cur = new Node(date);
cur->_col = red;
if (_com(parent->_date) < _com(date))
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
cur->_parent = parent;
//Node* uncle=parent->_parent->
while(parent && parent->_col == red)
{
Node* grandfater = parent->_parent;
assert(grandfater);
assert(grandfater->_col==black);
if (parent == grandfater->_left)
{
Node* uncle = grandfater->_right;
// 情况一 : uncle存在且为红,变色+继续往上处理
if (uncle && uncle->_col == red)
{
parent->_col = uncle->_col = black;
grandfater->_col = red;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}// 情况二+三:uncle不存在 + 存在且为黑
else
{
// 情况二:右单旋+变色
// g
// p u
// c
if (cur == parent->_left)
{
RotateR(grandfater);
parent->_col = black;
grandfater->_col = red;
}
else
{
// 情况三:左右单旋+变色
// g
// p u
// c
RotateL(parent);
RotateR(grandfater);
cur->_col = black;
grandfater->_col = red;
}
break;
}
}
else
{
Node* uncle = grandfater->_left;
// 情况一
if (uncle && uncle->_col == red)
{
parent->_col = uncle->_col = black;
grandfater->_col = red;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}
else
{
// 情况二:左单旋+变色
// g
// u p
// c
if (cur == parent->_right)
{
RotateL(grandfater);
parent->_col = black;
grandfater->_col = red;
}
else
{
// 情况三:右左单旋+变色
// g
// u p
// c
RotateR(parent);
RotateL(grandfater);
cur->_col = black;
grandfater->_col = red;
}
break;
}
}
}
_root->_col = black;
return make_pair(iterator(cur), true);
}
void Inorder()
{
_Inorder(_root);
}
private:
//右旋
void RotateR(Node* parent)
{
Node* subl = parent->_left;
Node* sublr = subl->_right;
Node* prev = parent->_parent;
parent->_left = sublr;
if (sublr)
sublr->_parent = parent;
parent->_parent = subl;
subl->_right = parent;
if (_root == parent)
{
_root = subl;
subl->_parent = nullptr;
}
else
{
if (prev->_left == parent)
{
subl->_parent = prev;
prev->_left = subl;
}
else
{
subl->_parent = prev;
prev->_right = subl;
}
}
}
//左旋
void RotateL(Node* parent)
{
Node* subr = parent->_right;
Node* subrl = subr->_left;
Node* prev = parent->_parent;
parent->_right = subrl;
if (subrl)
subrl->_parent = parent;
subr->_left = parent;
parent->_parent = subr;
if (_root == parent)
{
_root = subr;
subr->_parent = nullptr;
}
else
{
if (prev->_left == parent)
{
subr->_parent = prev;
prev->_left = subr;
}
else
{
subr->_parent = prev;
prev->_right = subr;
}
}
}
//遍历
void _Inorder(Node* _root)
{
if (_root == nullptr)
return;
_Inorder(_root->_left);
cout << _root->_date.first << " " << _root->_date.second << endl;
_Inorder(_root->_right);
}
private:
Node* _root = nullptr;
};
}