难以理解libstdc ++的Red-black树迭代器

时间:2018-10-01 14:41:27

标签: c++ stl iteration red-black-tree

我正在尝试为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以来)。

0 个答案:

没有答案