【问题标题】:Right Threading a Binary Tree右线程二叉树
【发布时间】:2009-07-29 18:11:40
【问题描述】:

我正忙着想办法解决这个问题。无论我在哪里看,我似乎都只是在解释如何以非递归方式实际遍历列表(我真正理解的部分)。那里的任何人都可以敲定我最初如何准确地浏览列表并找到实际的前任/后继节点,以便我可以在节点类中标记它们吗?我需要能够创建一个简单的二叉搜索树并浏览列表并将空链接重新路由到前任/继任者。我有一些类似以下的解决方案的运气:

thread(node n, node p) {
     if (n.left !=null)
        thread (n.left, n);
     if (n.right !=null) {
        thread (n.right, p);
     }
     n.right = p;
}

【问题讨论】:

  • 找到前任/后继节点?这和父母和孩子一样吗?你为什么要创造一棵有洞的树?
  • 为了澄清没有完全理解您的问题的其他人,我猜您正在尝试将二叉树的每个节点链接到其有序的前任和后继(如此处所述:@ 987654321@),对吧?

标签: algorithm binary-tree binary-search-tree


【解决方案1】:

根据您的描述,我假设您有一个结构类似于以下内容的节点:

Node {
  left
  right
}

... 并且您有一个使用左右设置的二叉树,并且您希望为左右重新分配值,以便它首先从深度创建一个双链表遍历树。

到目前为止,您所获得的根(没有双关语)问题是遍历期间传递的“节点 p”(previous 的缩写?)需要独立于您当前在树中的位置- 它总是需要包含以前访问过的节点。为此,每次运行线程时,它都需要引用相同的“先前”变量。我用一个 C-ism 编写了一些 Python 风格的伪代码 - 如果你不熟悉,'&' 表示“引用”(或 C# 中的“ref”),而 '* ' 的意思是“取消引用并给我它指向的对象”。

Node lastVisited
thread(root, &lastVisisted)

function thread(node, lastVisitedRef)
  if (node.left)
    thread(node.left, lastVisitedRef)
  if (node.right)
    thread(node.right, lastVisitedRef)

  // visit this node, reassigning left and right
  if (*lastVisitedRef)
    node.right = *lastVisitedRef
    (*lastVisitedRef).left = node
  // update reference lastVisited
  lastVisitedRef = &node

如果你打算在 C 中实现这个,你实际上需要一个双指针来保存引用,但想法是一样的——你需要在整个遍历过程中保持“最后访问的节点”的位置.

【讨论】:

    猜你喜欢
    • 2012-01-09
    • 2012-02-28
    • 2012-03-02
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多