簡體   English   中英

C 中的二叉樹

[英]Binary Trees in C

我正在嘗試按順序將節點插入樹中。 我的 function 工作正常......當只有三個節點時。

我有這個代碼:

typedef struct _Tnode Tnode;
struct _Tnode {
    char* data;
    Tnode* left;
    Tnode* right;
};

除此之外:

Tnode* add_tnode(Tnode* current_node, char* value) {
Tnode* ret_value; 

if(current_node == NULL) {
    current_node = (Tnode*) malloc(sizeof(Tnode));

    if(current_node != NULL) {
      (current_node)->data = value;
      (current_node)->left = NULL;
      (current_node)->right = NULL;
      ret_value = current_node; }
    else 
        printf("no memory");    
}
else {
    if(strcmp(current_node->data,value)) {  //left for less than 

        ret_value = add_tnode((current_node->left), value);
        current_node -> left = (Tnode*) malloc(sizeof(Tnode));
        (current_node -> left) -> data = value;
    }

    else if(strcmp(current_node->data,value) > 0) {

        ret_value = add_tnode((current_node -> right), value);
        current_node -> right = (Tnode*) malloc(sizeof(Tnode));
        (current_node -> right) -> data = value;
    }

    else {
        printf("duplicate\n");
        ret_value = current_node;
    }
}

return ret_value;

}

我知道這里出了什么問題,我只是不知道如何解決它。 這只是覆蓋連接到根節點的兩個節點。 IE

         |root_node|
        /           \
|node_2|             |node_3|

我無法添加節點 4。 它只是根據輸入覆蓋節點 2 或 3。 經過調試和一些研究,我不太確定 go 從這里到哪里......

如果有人可以提供幫助,我將不勝感激。

這似乎只是一個學校項目。

從哪里開始。

1)你一直在樹下左右搖擺。 我不確定您為什么希望它們被保留,因為:a)您總是寫入這些節點。 b)您返回現有節點的唯一時間是在 strcmp 匹配上。

2)您確實需要在第一次比較時檢查 strcmp < 0 。

3)對於非平衡樹,沒有理由使用遞歸 - 您可以使用循環直到到達葉子然后鈎住葉子。 如果你真的想要遞歸......

4) 遞歸...在所有情況下都返回 NULL,除非您創建一個節點(即:您擁有當前 == NULL 的第一部分)。

5)在左/右,將返回值存儲在臨時本地節點*中。 只有當返回值不是 NULL 時才應該分配左/右。

即使這對我來說也不合適,但如果我從頭開始,它看起來根本不會像這樣。 :) 我們甚至不會涉及到 memory 泄漏/崩潰,您可能會因為隨便按 'char *' 值而結束。

您應該只在插入到達葉節點(即NULL)的情況下進行分配。 在其他情況下,您應該做的就是根據您的比較遍歷到下一個級別。 在您的情況下,您正在進入下一個級別,然后使用新的 malloc 將其殺死。 正因為如此,你永遠不會超過第一級。

例如。

if (current_node == NULL) // Do initialization stuff and return current_node

if (strcmp(current_node->data, value) < 0) {
    current_node->left = add_tnode((current_node->left), value);
} else if (strcmp(current_node->data, value) > 0) {
    current_node->right = add_tnode((current_node->right), value);
}

return current_node;
struct _Tnode {
        char* data;
        struct _Tnode * left, * right;
    };
    typedef struct _Tnode Tnode;

void addNode(Tnode ** tree, Tnode * node){

    if(!(*tree)){
        *tree = node;
        return;
    }

    if(node->data < (*tree)->val){
       insert(&(*tree)->left, node);
    }else if(node->data>(*tree)->data){
       insert(&(*tree)->right, node);
    }

}

對於初學者 - 第一個 strcmp

if(strcmp(current_node->data,value))

可能是不正確的 - 這對於小於和大於都是正確的,然后第二個 if 沒有意義

我想您需要將指向父節點的指針添加到_Tnode結構。

問題是,在對左側分支上的 add_tnode 進行遞歸 function 調用之后,例如,您正在用 malloc 消除同一分支。 malloc 應該只在您遞歸到要添加節點的點時發生,而不是在您進行遞歸調用時發生。

本質上,在特定的 function 調用中,您應該進行遞歸調用或 malloc 一個新節點,而不是兩者。

這也可能會產生 memory 泄漏。

一旦發現 current_node->data 不是 null 並將其與 value 進行比較,您首先必須檢查相應的指針 current_node->left(或 ->right)是否已在使用中(.= NULL)。

如果是 null,則照常進行。 這就是現在工作正常的情況。

如果沒有,您必須針對相應節點重新測試整個事情,在相應節點上再次調用您的 function。 這里有一些偽代碼:

用以下代碼包裝代碼:

void Add_node(Tnode* current_node) {
...
else {
        if(strcmp(current_node->data,value) < 0) {  //left for less than 
           if(current_node->left != NULL) {
                Add_node(current_node->left);
           } else {
                ret_value = add_tnode((current_node->left), value);
                current_node -> left = (Tnode*) malloc(sizeof(Tnode));
                (current_node -> left) -> data = value;
        } else if(strcmp(current_node->data,value) > 0) {
                Add_node(current_node->right);
           } else {
           ...
}

這稱為遞歸(function 調用本身)並遍歷樹。 要讀取某個節點,您必須再次執行遞歸 function。 小心它們終止(在某些時候左或右指針將是 null,從而終止遞歸調用)。

如果您不是為了自己的啟迪而實施它,我只會使用libavl

您不需要知道節點的父節點。 只是當前節點的值。

偽代碼:

add_treenode(root, value)

{

 //check if we are at a leaf  
 if root == null
     allocate space for new node.
     set children to null
     save root->value = value
     return root // if you need to return something, return the node you inserted.
 //if not, this node has a value
 if root->value < value  //use strcmp since value is a string
       add_tnode(root->left, value)
 else
       add_tnode(root->right, value)
 return NULL

}

在插入新樹節點時,這與它一樣干凈。 傳遞要插入的節點的根和值,它執行 rest。

暫無
暫無

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

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