我正在尝试为Ternary Search Tree实现迭代器,并且由于TST与BST非常相似,所以我认为我将研究libstdc++
对于上述迭代器的实现。这个想法是遍历所有树节点,而不修改树或在迭代器中保存当前树节点以外的任何内容。树节点具有父指针以允许这种迭代。
这是来自GitHub mirror的最新GCC代码:
static _Rb_tree_node_base*
local_Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
{
if (__x->_M_right != 0)
{
__x = __x->_M_right;
while (__x->_M_left != 0)
__x = __x->_M_left;
}
else
{
_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_right)
{
__x = __y;
__y = __y->_M_parent;
}
if (__x->_M_right != __y)
__x = __y;
}
return __x;
}
它看起来很简单,递增操作要么将您带到您的右子,然后一直到左,要么将您带到第一个非右父。我不明白的是第二个if
子句:
if (__x->_M_right != __y)
__x = __y;
这种情况如何评估为false
?为此,__x
需要超过__y
,而在while
循环中似乎是不可能的。我认为如果树是threaded tree可能是false
,但是第一个nullptr
子句中的if
检查似乎暗示了其他情况。另外,删除if
子句并仅在我的代码中编写__x = __y;
似乎并没有破坏任何东西。
这是怎么回事?
修改:
这是Clang的libc++
的代码。似乎这次if
没有保护相同的代码:
template <class _EndNodePtr, class _NodePtr>
inline _LIBCPP_INLINE_VISIBILITY
_EndNodePtr
__tree_next_iter(_NodePtr __x) _NOEXCEPT
{
if (__x->__right_ != nullptr)
return static_cast<_EndNodePtr>(__tree_min(__x->__right_));
while (!__tree_is_left_child(__x))
__x = __x->__parent_unsafe();
return static_cast<_EndNodePtr>(__x->__parent_);
}
我怀疑if是否多余,因为它已经存在了至少二十年了(自SGI以来)。