C 为什么这个指针算法不起作用?

C 为什么这个指针算法不起作用?,c,pointers,binary-tree,C,Pointers,Binary Tree,在我的程序中,我有一个二叉树,定义如下: struct node { char value; struct node *left, *right; }; 在我的程序中,我试图编写一个函数,该函数按索引顺序(从上到下,从右到左遍历)返回每个节点值的字符串 为此,我编写了以下函数: char *to_string_util(struct node *root, char *str) { if (!root) return str; *str++ = root-

在我的程序中,我有一个二叉树,定义如下:

struct node {
    char value; 
    struct node *left, *right;
};
在我的程序中,我试图编写一个函数,该函数按索引顺序(从上到下,从右到左遍历)返回每个节点值的字符串

为此,我编写了以下函数:

char *to_string_util(struct node *root, char *str) {

    if (!root) return str;

    *str++ = root->value;

    // If not NULL
    if (root->left) to_string_util(root->left, str);
    if (root->right) to_string_util(root->right, str);

    return str;
}
这似乎应该奏效,但可惜没有。我已经通过使用数组索引使其工作,这是可行的,但不可取的,因为它需要引入另一个变量

以下是有效的版本:

char *to_string_util(struct node *root, char *str, int *cur_pos) {

    if (!root) return str;

    str[(*cur_pos)++] = root->value;

    if (root->left) to_string_util(root->left, str, cur_pos);

    if (root->right) to_string_util(root->right, str, cur_pos);

    return str;
}
鉴于这棵树:

             +
           /   \
          *     *
         / \   / \
         a  a  b  b 
结果应该是:
+*aa*bb

需要注意的一点是,我在另一个函数中调用了这个函数,该函数在它的末尾附加了一个空字符,这不应该影响输出,但我认为可能值得一提


为什么使用数组索引的第二个版本有效,而第一个版本无效?

它无效,因为您忽略了递归子调用返回的新值
str
。您的函数用于更新
str
的值,并通过执行
return str返回新值。您只是在丢弃返回的值。因此,在每个递归级别,对右子树的调用都会覆盖由对左子树的递归调用写入的数据

这可能更接近你的想法

// If not NULL
if (root->left) str = to_string_util(root->left, str);
if (root->right) str = to_string_util(root->right, str);
当然,您应该记住在最后以零结束字符串


如果函数以

if (!root) return str;
然后递归子调用实际上不需要空检查,可以简化为

str = to_string_util(root->left, str);
str = to_string_util(root->right, str);
(除非您将其视为优化)


基于索引的版本不再依赖于
str
的更新(并且根本不更新)。它取决于位置值的更新
*cur\u pos
。由于位置值是通过引用在不同递归级别之间传递的,因此所有递归级别都会看到这些更新


您也可以在第一个版本中使用相同的技术,即通过引用传递指针值。但为此,您必须将
str
作为
char**str
(指向指针的指针)传递,并使用
*str
和当前字符指针。

它不起作用,因为您忽略了递归子调用返回的
str
的新值。您的函数用于更新
str
的值,并通过执行
return str返回新值。您只是在丢弃返回的值。因此,在每个递归级别,对右子树的调用都会覆盖由对左子树的递归调用写入的数据

这可能更接近你的想法

// If not NULL
if (root->left) str = to_string_util(root->left, str);
if (root->right) str = to_string_util(root->right, str);
当然,您应该记住在最后以零结束字符串


如果函数以

if (!root) return str;
然后递归子调用实际上不需要空检查,可以简化为

str = to_string_util(root->left, str);
str = to_string_util(root->right, str);
(除非您将其视为优化)


基于索引的版本不再依赖于
str
的更新(并且根本不更新)。它取决于位置值的更新
*cur\u pos
。由于位置值是通过引用在不同递归级别之间传递的,因此所有递归级别都会看到这些更新

您也可以在第一个版本中使用相同的技术,即通过引用传递指针值。但为此,您必须将
str
作为
char**str
(指向指针的指针)传递,并使用
*str
和当前字符指针