簡體   English   中英

構建帶有負節點的表達式樹

[英]Building Expression tree with negative nodes

我在構建這樣的二叉樹時遇到了麻煩: view tree 你可以看到有一些操作數節點,比如-他們只有一個孩子。 即使使用像+-a這樣的簡單樹,代碼也不起作用。

我的代碼是:

    // Represents a node of the required tree 
typedef struct node { char data; struct node *left, *right; } node; 

// Function to recursively build the expression tree 
char* add(node** p, char* a) 
{ 

// If its the end of the expression 
if (*a == '\0') 
    return '\0'; 

while (1) { 
    char* q = "null"; 
    if (*p == NULL) { 

        // Create a node with *a as the data and 
        // both the children set to null 
        node* nn = (node*)malloc(sizeof(node));
        nn->data = *a; 
        nn->left = NULL; 
        nn->right = NULL; 
        *p = nn; 
    } 
    else { 

        // If the character is an operand 
        if (*a >= 'a' && *a <= 'z') { 
            return a; 
        } 

        // Build the left sub-tree 
        q = add(&(*p)->left, a + 1); 

        // Build the right sub-tree 
        q = add(&(*p)->right, q + 1); 

        return q; 
    } 
  } 
} 

int main() 
    { 
    node* s = NULL; 
    char a[] = "+-a"; 
    add(&s, a); 
    return 0; 
    }

感謝您的幫助<3

片段上存在矛盾和沒有意義的東西。 很難知道從哪里開始解釋正在發生的事情。

我想開始的一件事是這不是應用遞歸的好地方。 問題的一部分本質上是迭代的:您想要遍歷字符串。 將此與遞歸算法相結合顯然會讓您頭疼,因為您根本沒有做好。 一般來說,遞歸是一個陷阱,使事情迭代導致代碼更清晰。 “需要”遞歸的數據結構也經常是陷阱。

無論如何,我最終會提出一個可行的遞歸算法。 現在,要剖析你做錯了什么。 從 add 返回一個 char 指針立即是一個巨大的危險信號:讓指針算法在遞歸中工作很困難,因為更改必須在調用堆棧中體現出來。 從代碼中消除這一點是一個明顯的開始。

接下來是while循環。 循環本質上是一個迭代的東西,但是你將它包含在一個遞歸算法中:希望它固有的迭代性質開始變得清晰。 你有 while 循環的原因也很愚蠢:你用一個完全沒有必要的 if-else 進行拆分。 正確的做法是在沒有 if 的情況下每次調用都分配一個新節點,因為您永遠不會按原樣在已經存在的節點上遞歸,而且您絕對不需要 else,因為遞歸邏輯需要發生,無論是否是否必須分配新節點。 因此,刪除 while 循環和 if-else。

接下來是 q 變量。 我不知道你想用它做什么,但無論如何它都是垃圾。 已移除。 分配新節點時的一個小問題是,您不需要新變量來分配新節點:您可以簡單地使用 *p。 這節省了一行代碼。

最后我們進入遞歸邏輯。 我已經談到了 q 的事情,所以不需要詳細說明。 這里的邏輯根本不起作用,因為您沒有以正確的方式遍歷字符串。 再次,以遞歸算法執行此操作比以迭代方式編寫它更難。

所以,這是實際工作的代碼。 我非常自由地壓縮源代碼,這樣算法在垂直方向上占用的空間更少,因為節省 LoC 是一件好事。

int add(node** p, char* a, int i) {
    if (a[i] == '\0') return i; // If end of expression 
     *p = (node*) malloc(sizeof(node));
    (*p)->data = a[i];
    (*p)->left = (*p)->right = NULL;
    if (a[i] >= 'a' && a[i] <= 'z') return i;   // If the character is an operand 
    i = add(&(*p)->left , a, ++i);
    if (a[i] == '\0')   return i;   // If its the end of the expression 
    i = add(&(*p)->right, a, ++i);
    return i;
}

i 變量用於計算通過字符串的路徑。 您必須修改 main 中的初始添加調用以適應。

暫無
暫無

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

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