Algorithm 修改二叉树的顺序遍历

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,依此类

这是在一次采访中问我的,我搞砸了。我们得到了一个二叉树,但是,它被修改为它的子节点永远不会为null,如果一个非叶节点没有子节点,那么它的右/左子节点指向节点本身。对于叶节点,它们指向下一个左节点和右节点。对于最左边和最右边的节点,它将指向自身和上一个/下一个元素

例如:

        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