【问题标题】:Why does this pointer arithmetic not work?为什么这个指针算法不起作用?
【发布时间】:2017-08-11 06:55:43
【问题描述】:

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

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

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

为什么使用数组索引的第二个版本可以工作,而第一个却不行?

【问题讨论】:

    标签: c pointers binary-tree


    【解决方案1】:

    它不起作用,因为您忽略了从递归子调用返回的 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_pos 的更新。由于位置值在不同级别的递归之间传递通过引用,所有级别的递归都会看到这些更新。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      相关资源
      最近更新 更多