我有一段时间试图想出这个。无论我到哪里,我似乎只是在解释如何以非递归方式实际遍历列表(我实际理解的部分)。任何人都可以知道我最初是如何完成列表并找到实际的前任/后继节点以便我可以在节点类中标记它们吗?我需要能够创建一个简单的二进制搜索树并浏览列表并将空链接重新路由到前任/后继。我有一些运气的解决方案,如下所示:
thread(node n, node p) {
if (n.left !=null)
thread (n.left, n);
if (n.right !=null) {
thread (n.right, p);
}
n.right = p;
}
答案 0 :(得分:1)
根据您的描述,我假设您的节点结构类似于:
Node {
left
right
}
...并且您使用左侧和右侧设置了这些设置的二叉树,并且您想要向左和向右重新分配值,以便它首先从深度创建双重链接列表穿越树。
到目前为止你所获得的根(没有双关语)问题是在遍历期间传递的“节点p”(前一个的简称?)需要独立于当前树中的位置 - 它总是需要包含以前访问过的节点。为此,每次运行线程时,它都需要引用相同的“previous”变量。我已经用一个C-ism做了一些Python-ish伪代码 - 如果你不熟悉,'& '意味着“引用”(或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中实现它,你实际上需要一个双指针来保存引用,但想法是一样的 - 你需要在整个遍历期间保持“最后访问过的节点”的位置