文章目录
1、泛型红黑树
1.1 set与map
set:
上图我们可以看到set底层使用的是红黑树,而他的value值存的却是Key的值,
map:
我们发现map的底层也是红黑树,而map的value的值却是pair<const K,T>类型的
对于不同的传值要求如果要造两棵红黑树的话是一种治标不治本的效果,所以我们要造出一个泛型红黑树,任何值都可以接受。
相较于上一章的红黑树我们就需要更改。
1.2 节点的更改
使用模板,这样传过来的值都可以接受。
template <class T>
struct RBTreeNode
{
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
Color _col;
T _data;
RBTreeNode(const T& data)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _col(RED)
, _data(data)
{}
};
1.3 插入的更改
对于插入唯一需要着重的点是set和map传值类型不同,那么相对于值比较也需要不同的方法,所以我们可以在这两个类里面做一个特定的仿函数,来提取想要比较的值。
仿函数提取set中的比较值:
struct SetKeyOfT
{
const K& operator()(const K& key)
{
return key;
}
};
仿函数提取map中的比较值:
struct MapKeyOfT
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
插入的具体更改:
通过仿函数来提取具体的值来进行比较。
if (key(cur->_data) < key(data))
{
parent = cur;
cur = cur->_right;
}
else if (key(cur->_data) > key(data))
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
2、set与map的迭代器
由于我么这两个类用的是同一个红黑树,所以我们可以把迭代器具体实现放在红黑树中方便使用。
构建一个迭代器结构体:
struct RBTreeIterator
{
typedef RBTreeNode<T> Node;
typedef RBTreeIterator<T> Self;
Node* _node;
RBTreeIterator(Node* node)
:_node(node)
{}
}
运算符*
T& operator*()
{
return _node->_data;
}
运算符->
T* operator->()
{
return &_node->_data;
}
运算符++
1、因为红黑树的中序是有序的,所以++是找到该节点在中序中的下一个节点
2、因为中序是左中右,所以我们可以分为右子树存在和不存在来讨论下一个节点是谁
3、当右子树存在时,右子树的最左节点即是下一个节点
4、当右子树不存在时,我们需要向上寻找,因为中序是左中右的,所以该子树已经被遍历完了,则++操作后应该在该结点的祖先结点中找到孩子不在父亲右的祖先
Self& operator++()
{
if (_node->_right)
{
Node* subl = _node->_right;
while (subl->_left)
{
subl = subl->_left;
}
_node = subl;
}
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->_left)
{
Node* subr = _node->_left;
while (subr->_right)
{
subr = subr->_right;
}
_node = subr;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_left)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
}
运算符!=
bool operator!=(const Self& s)
{
return _node != s._node;
}
运算符==
bool operato==(const Self& s)
{
return _node == s._node;
}
begin()与end()
iterator begin()
{
Node* subLeft = _root;
while (subLeft && subLeft->_left)
{
subLeft = subLeft->_left;
}
return iterator(subLeft);
}
iterator end()
{
return iterator(nullptr);
}
set与map的类封装
set:
#pragma once
#include "RBTree.h"
namespace zyf
{
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;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
bool insert(const K& key)
{
return _t.insert(key);
}
private:
RBTree<K, const K, SetKeyOfT> _s;
};
}
map:
#pragma once
#include "RBTree.h"
namespace zyf
{
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;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
bool insert(const pair<K, V>& kv)
{
return _t.Insert(kv);
}
bool insert(const pair<K, V>& kv)
{
return _m.insert(kv);
}
private:
RBTree < K, pair<K, V>,MapKeyOfT> _m;
};