1.红黑树的迭代器
迭代器的好处是可以方便遍历,使数据结构的底层实现与用户透明。如果想要给红黑树增加迭代器,需要考虑以下问题:
begin()与end()
STL明确规定,begin()与end()代表的是一段前闭后开的区间,而对红黑树进行中序遍历后,可以得到一个有序的序列,因此:begin()可以放在红黑树中最小节点(即最左侧节点)的位置,end()放在最大节点(最右侧节点)的下一个位置,关键是最大节点的下一个位置在哪块?能否给成nullptr呢?答案是行不通的,因为对end()位置的迭代器进行–操作,必须要能找最后一个元素,此处就不行,因此最好的方式是将end()放在头结点的位置:
operator++()与operator–()
template<class T>
struct RBtreeIterator
{
typedef RBTreeNode<T> Node;
typedef RBtreeIterator<T> Self;
RBtreeIterator(Node* node = nullptr)
: pNode(node)
{
}
// 具有指针类似的方法
T& operator*()
{
return pNode->data;
}
T* operator->()
{
// return &(pNode->data);
return &(operator*());
}
// 可以移动
Self& operator++()
{
Increament();
return *this;
}
Self operator++(int)
{
Self temp(*this);
Increament();
return temp;
}
Self& operator--()
{
Decreament();
return *this;
}
Self operator--(int)
{
Self temp(*this);
Decreament();
return temp;
}
// 能够进行比较
bool operator==(const Self& s)const
{
return pNode == s.pNode;
}
bool operator!=(const Self& s)const
{
return pNode != s.pNode;
}
private:
void Increament()
{
// 前置++和后置++需要用来--->找比当前节点大的节点中值域最小的
if (pNode->right)
{
// 到pNode的右子树中找最左侧节点(最小的节点)
pNode = pNode->right;
while (pNode->left)
pNode = pNode->left;
}
else
{
// pNode没有右子树,只能往pNode的双亲中进行查找
Node* parent = pNode->parent;
while (parent->right == pNode)
{
pNode = parent;
parent = pNode->parent;
}
// 特殊情况:根节点没有右孩子场景
if (pNode->right != parent)
pNode = parent;
}
}
void Decreament()
{
// 找比当前节点小的所有节点中值最大的节点
// 左子树中找最大节点 也可以再其双亲中找
if (pNode->parent->parent == pNode && RED == pNode->color)
{
// pNode已经在end的位置
pNode = pNode->right;
}
else if (pNode->left)
{
// 左子树存在
pNode = pNode->left;
while (pNode->right)
pNode = pNode->right;
}
else
{
// 左子树不存在,只能在其双亲中进行查找
Node* parent = pNode->parent;
while (pNode == parent->left)
{
pNode = parent;
parent = pNode->parent;
}
pNode = parent;
}
}
Node* pNode;
};
2.改造红黑树
红黑树的实现,在之前的文章已经讲过,可以参考:
图文详解红黑树
此处是改造后的代码:
// T 表示红黑树中存放元素的类型
// KOFV: 表示获取元素中key的方式
template<class T, class KOFV>
class RBTree
{
typedef RBTreeNode<T> Node;
public:
typedef RBtreeIterator<T> iterator;
public:
RBTree()
{
head = new Node();
head->left = head;
head->right = head