请问有没有人能够在不使用栈或递归的情况下帮助我理解 Morris 中序遍历算法?我一直在尝试理解它的工作原理,但它总是让我无法理解。
1. Initialize current as root
2. While current is not NULL
If current does not have left child
a. Print current’s data
b. Go to the right, i.e., current = current->right
Else
a. In current's left subtree, make current the right child of the rightmost node
b. Go to this left child, i.e., current = current->left
我理解树是以这样的方式进行修改的:当前节点变为右子树中最大节点的右子节点,并且可以利用此属性进行中序遍历。但除此之外,我不知道其他了。编辑: 找到了这段伴随的C++代码。我一直很难理解树在修改后如何恢复。关键在于 else 子句,它在右叶子节点被修改后触发。详见代码:
/* Function to traverse binary tree without recursion and
without stack */
void MorrisTraversal(struct tNode *root)
{
struct tNode *current,*pre;
if(root == NULL)
return;
current = root;
while(current != NULL)
{
if(current->left == NULL)
{
printf(" %d ", current->data);
current = current->right;
}
else
{
/* Find the inorder predecessor of current */
pre = current->left;
while(pre->right != NULL && pre->right != current)
pre = pre->right;
/* Make current as right child of its inorder predecessor */
if(pre->right == NULL)
{
pre->right = current;
current = current->left;
}
// MAGIC OF RESTORING the Tree happens here:
/* Revert the changes made in if part to restore the original
tree i.e., fix the right child of predecssor */
else
{
pre->right = NULL;
printf(" %d ",current->data);
current = current->right;
} /* End of if condition pre->right == NULL */
} /* End of if condition current->left == NULL*/
} /* End of while */
}
pre->right = NULL;
- prashant.kr.modcurrent
的前任并向左移动。这应该说得更像是“如果我们在查找其自身前任时撞到了current
,则取消线程(可选,如果您不想保留树线程)并向右移动”。我认为这就是@Talonj在他们出色的答案中所说的“循环的双重条件”。这里的教训是代码胜过描述。 - bronzenose