[英]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.