目录
1.2operator*() && operator->()
1.5operator==() && operator!=()
一、红黑树的迭代器
前一篇章,有了红黑树的了解,但那只实现了红黑树的插入部分,那么现在要用红黑树封装set、map容器,那有一个功能,就必须得实现,即迭代器,对于红黑树的迭代器该如何实现呢?参考前面篇章,list容器的迭代器的实现,同样的,红黑树将迭代器要实现的功能封装成了一个类,那么接下来进行一步步实现。
1.1红黑树迭代器框架
由于迭代器的遍历,实际就是遍历节点,在实现具体步骤之前,先带上节点,再把迭代器的框架搭好。
enum Color//对于红黑节点,用枚举结构来表示
{
RED,
BLACK
};
template<class T>
struct RBTreeNode
{
RBTreeNode(const T& data, Color color = RED)
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_data(data)
,_color(color)
{}
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
T _data;
Color _color;//默认给红色才符合规则,若默认给黑色的话,则插入的每个节点都是黑色节点,
//那么就不能保证每条路径的黑色节点相同,违反了第4条性质。而给红色,就可以根据规则调整。
};
template<class T, class Ref, class Ptr>
struct RBTreeIterator
{
typedef RBTreeNode<T> Node;
typedef Node* PNode;
typedef RBTreeIterator<T, Ref, Ptr> Self;
PNode _node;
RBTreeIterator(const PNode node)
:_node(node)
{}
//.....
};
1.2operator*() && operator->()
T& operator*()
{
return _node->_data;//访问节点数据
}
T* operator->()
{
return &(operator*());//operator*() == _node->_data
}
1.3operator++()
对红黑树的遍历是一个中序遍历,遍历完后,得到的是一个有序序列。每++一次,跳到的位置是中序序列中的下一个位置。我们知道中序的访问顺序是,左根右,那么如何在树上进行操作而达到中序遍历呢?
大致可以分为两步:
1.当左子树与根访问完,要符合中序,得去右子树进行访问,同理右子树得满足中序遍历,首先就得找到右子树的最小节点,即最左节点。
抽象示意图:
2.当左子树未访问完,++时,就指向父节点,
抽象示意图:
或者当右子树访问完了,则说明一颗节点的整个左子树访问完了。那么++就是要找到这个节点
抽象示意图:
Self& operator++()
{
if (_node->_right)//左子树访问完,去访问右子树
{
_node = _node->_right;
while (_node && _node->_left)
{
_node = _node->_left;
}
}
else//左子树未访问完,或者右子树访问完
{
PNode cur = _node;
PNode parent = cur->_parent;
while (parent && cur != parent->_left)
{
cur = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
1.4operator--()
那么,对于--操作,它与++操作是反过来的,是从大到小的一个遍历。
1. 当右子树与根访问完,要符合大到小的遍历,得去左子树进行访问,同理左子树得满足大到小的遍历,首先就得找到左子树的最大节点,即最右节点。
2.当右子树未访问完,或者左子树已访问完
Self& operator--()
{
PNode cur = _node;
PNode parent = cur->_parent;
if (_node->_left)//右子树访问完,去左子树访问
{
_node = _node->_left;
while (_node->_right)
{
_node = _node->_right;
}
}
else//右子树未访问完,或者左子树访问完
{
PNode cur = _node;
PNode parent = cur->_parent;
if (parent && cur != parent->_right)
{
cur = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
1.5operator==() && operator!=()
bool operator==(const Self& x) const
{
return _node ==