簡體   English   中英

為什么此指針算法不起作用?

[英]Why does this pointer arithmetic not work?

在我的程序中,我有一個二進制樹,其定義如下:

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的新值。 您的函數旨在通過執行return 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的更新。 由於位置值是通過引用在不同遞歸級別之間傳遞的,因此所有遞歸級別都可以查看這些更新。

您也可以在第一個版本中使用相同的技術,即通過reference傳遞指針值。 但是為此,您必須將str作為char **str (指針到指針)傳遞,並使用*str和當前字符指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM