Algorithm 修改二叉树的顺序遍历
这是在一次采访中问我的,我搞砸了。我们得到了一个二叉树,但是,它被修改为它的子节点永远不会为null,如果一个非叶节点没有子节点,那么它的右/左子节点指向节点本身。对于叶节点,它们指向下一个左节点和右节点。对于最左边和最右边的节点,它将指向自身和上一个/下一个元素 例如:Algorithm 修改二叉树的顺序遍历,algorithm,recursion,language-agnostic,tree,Algorithm,Recursion,Language Agnostic,Tree,这是在一次采访中问我的,我搞砸了。我们得到了一个二叉树,但是,它被修改为它的子节点永远不会为null,如果一个非叶节点没有子节点,那么它的右/左子节点指向节点本身。对于叶节点,它们指向下一个左节点和右节点。对于最左边和最右边的节点,它将指向自身和上一个/下一个元素 例如: 1 / \ 2 3 / \ / \ (4 = 5 = 6 = 7) 这里4.left=4,4.right=5,5.left=4和5.right=6,依此类
1
/ \
2 3
/ \ / \
(4 = 5 = 6 = 7)
这里4.left=4,4.right=5,5.left=4和5.right=6,依此类推
我们需要按顺序遍历这棵树
我提出了确定节点是否为叶节点的条件(退出条件):
但是不能正确地结合这些。此外,我们还需要注意甚至根满足条件root.left=root | | root.right=right的偏斜树,因此我们将直接退出递归,甚至不遍历整个树
请帮帮我。我无法对递归进行适当的条件检查
我们只需要按顺序遍历这棵树。输出:4 2 5 1 6 3 7如果命中一个指向右侧自身但左侧有子节点的非叶,则类似“root.right==root”的条件将错误地将该节点称为叶。您需要使用and语句。我认为这可能有效:
if((root.right==root && root.left.right == root) || (root.left == root && root.right.left == root) || (root.left.right == root && root.left == root))
但是如果你有一棵中间缺叶子的树,那就不行了。当然,如果对节点进行了编号,那么就更容易了,因为您只需使用log2来检查与链接位置相比它处于什么级别。以下算法应该可以:
visit(vertex v) {
if (v.left != v && v.left.right != v) visit(v.left)
print v
if (v.right != v && v.right.left != v) visit(v.right)
}
我认为你的问题是你试图一次做太多的事情。与其检测顶点是否是叶子,不如先检测它是否有左子对象,然后检测它是否有右子对象 为了清晰起见,我将所有奇怪的逻辑放入一个函数(可以内联)
你能给出一个原因/例子吗?
visit(vertex v) {
if (v.left != v && v.left.right != v) visit(v.left)
print v
if (v.right != v && v.right.left != v) visit(v.right)
}
#include <stdio.h>
struct list {
struct list *prev;
struct list *next;
int val;
};
struct list arr[] =
{ {arr+1, arr+2, 1}
, {arr+3, arr+4, 2}
, {arr+5, arr+6, 3}
, {arr+3, arr+4, 4}
, {arr+3, arr+5, 5}
, {arr+4, arr+6, 6}
, {arr+5, arr+6, 7}
};
int is_leaf(struct list *p)
{
if (p->prev == p) return 1; // 4
if (p->next == p) return 1; // 7
if (p->next->prev == p) return 1; // 5,6
return 0; // non-leaves : 1,2,3
}
unsigned recurse (struct list *p)
{
int chk;
unsigned ret=1;
chk = is_leaf(p) ;
if (!chk) ret+=recurse(p->prev);
printf("%d %s\n", p->val, chk ? "leaf" : "nonLeaf" );
if (!chk) ret+=recurse(p->next);
return ret;
}
int main (void) {
unsigned cnt;
cnt = recurse (arr);
printf( "Result=%u\n", cnt );
return 0;
}
4 leaf
2 nonLeaf
5 leaf
1 nonLeaf
6 leaf
3 nonLeaf
7 leaf
Result=7