C ++ - 线程树,有序遍历

时间:2010-12-08 16:12:58

标签: c++ binary-tree

我刚刚用C ++实现了一个线程树,现在我正按顺序尝试cout所有元素。

在我使用它之前,树是一个二进制排序树(不平衡)。

我试过这样做:

E min = _min(root); //returns the minimum element of the tree
E max = _max(root); //returns the maximum element of the tree

while (min != max)
{
  std::cout << min << ", ";
  min = _successor(root, min);
}
std::cout << max << ", ";
std::cout << std::endl;

但是由于树现在是线程化的,我的后继函数总是返回整个树的最小值(基本上,它在右子树中一次,然后尽可能多地在左子树中,直到它找到一个因此,当我尝试调用此函数时,它只有cout 1(因为1是我树的最小值)。

另外,我尝试了其他的东西:

  E min = _min(root); //returns min element of the tree
  E max = _max(root); //returns max element of the tree
  Node* tmp = _getNode(root, min); //returns the node of the specified element, therefore the minimum node of the tree
  while(tmp->data < max)
  {
           std::cout << tmp->data << ", ";
           tmp = _getNode(root, tmp->data)->rightChild; //gets the right child node of tmp
  }
  std::cout << tmp->data << ", ";

然而,通过这样做,有些值被忽略。 (见下图) alt text

(在树的线程化之后添加了绿色链接。) 例如,如果你看到节点#6永远不会从最后一个算法中被访问,因为它不是树中任何节点的正确子节点...

这是上一个函数的输出:

1, 2, 3, 5, 7, 8, 11, 71

有没有人知道如何解决这个问题,或者我的问题的任何提示?

由于

编辑:毕竟我只需要从最小值到最大值遍历树并修改我的_predecessor和_successor方法,因此他们不会检查有线程的子树。 :)

希望它能帮助未来的读者。

3 个答案:

答案 0 :(得分:2)

尝试

Node* n = _min(root);
while (n->right) {
    cout << n->val << ", ";
    n = _successor(n);
}
cout << n->val << endl;

这基本上是你的第一个代码(请注意,我假设树是非空的,就像你一样)。这也不会给你一个尾随','。

重要的是让你的继任者功能正确。它应该是这样的

Node* _successor(Node* n) {
    if (is_thread(o, RIGHT)) return o->right;
    return _min(o->right);
}

为了完整性

Node* _min(Node* n) {
    while (!is_thread(o, LEFT)) n = o->left;
    return n;
}

对于这两个,所有绿色箭头都是线程。

答案 1 :(得分:1)

我之前从未见过螺纹树,但无论如何我都会对此进行刺穿。要构建顺序遍历,您可以同时从两个方向接近树的根:

  1. 从根开始。
  2. 按照所有左侧链接,直到找到一个指向null的链接。该元素是树的最小值。
  3. 按照所有权利链接,直至到达根目录。如果您正确构建了树,则应该按递增顺序遍历每个元素。
  4. 以相反方向重复步骤2和3(找到最大元素,向后走)。
  5. 将这两个列表加入中间的根目录。
  6. 这可能不是最快的算法,但我认为它会产生正确的答案。而且你不必使用递归,我猜这是使用线程树的全部要点。

答案 2 :(得分:0)

毕竟我只需要从最小到最大遍历树 和 修改我的_predecessor和_successor方法,这样他们就不会检查有线程的子树。 :)

希望它能帮助未来的读者。