我正在尝试实施通常的'插入' C语言中的二叉树函数,我无法弄清楚我的代码错误的位置(这是错误的,但是,因为它不起作用......)。
有人可以帮我弄清楚我做错了吗?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
struct node *left;
struct node *right;
int data;
} node;
void insert (node *root, int n);
void print (node *root);
int main(void){
node *root = malloc(sizeof(node));
root->left = root->right = NULL;
root->data = 50;
insert (root, 1);
}
void insert (node *root, int n){
node *cursor = root;
while (cursor != NULL){
if (n <= cursor->data){
cursor = cursor->left;
printf("left\n");
}
else if (cursor->data < n){
cursor = cursor->right;
printf("right\n");
}
else {
printf("Invalid data in the tree.\n");
return;
}
}
cursor = malloc(sizeof(node));
printf("%p\n", root->left);
cursor->data = n;
cursor->left = NULL;
cursor->right = NULL;
}
void print (node* root){
if (root == NULL){
return;
}
print(root->left);
printf("%i ", root->data);
print(root->right);
}
答案 0 :(得分:4)
您分配给cursor
,而cursor->left
或cursor->right
未分配。
确保cursor->left
或cursor->right
指向新分配的节点。
void insert (node *root, int n){
node *cursor = root;
while (cursor != NULL){
if (n <= cursor->data){ /* Change 1 follows */
printf("left\n");
if(cursor->left == NULL) {
cursor->left = malloc(sizeof(node));
cursor = cursor->left;
break;
}
}
else if (cursor->data < n){
printf("right\n");
if(cursor->right == NULL) { /* Change 2 follows */
cursor->right = malloc(sizeof(node));
cursor = cursor->right;
break;
}
}
else {
printf("Invalid data in the tree.\n");
return;
}
}
/* Change 3 : 1 line deleted */
printf("%p\n", root->left); /* Why? */
cursor->data = n;
cursor->left = NULL;
cursor->right = NULL;
}
答案 1 :(得分:1)
您需要保留对之前cursor
的引用。你需要找到cursor->data
为空的地方;但是如果你想找到cursor
本身为空的地方,它对你没有任何作用,因为cursor
不是对前一个cursor->data
的引用,而是一个副本:如果您更改cursor
,则结构中的任何内容都不会更改。
答案 2 :(得分:0)
您的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
struct node *left;
struct node *right;
int data;
} node;
void insert (node *root, int n);
void print (node *root);
int main(void){
node *root = malloc(sizeof(node));
root->left = root->right = NULL;
root->data = 50;
insert (root, 1);
}
void insert (node *root, int n){
node *cursor = root;
while (cursor != NULL){
if (n <= cursor->data){
cursor = cursor->left;
printf("left\n");
}else if (cursor->data < n){
cursor = cursor->right;
printf("right\n");
}else {
printf("Invalid data in the tree.\n");
return;
}
}
cursor = malloc(sizeof(node));
printf("%p\n", root->left);
cursor->data = n;
cursor->left = NULL;
cursor->right = NULL;
}
void print (node* root){
if (root == NULL){
return;
}
print(root->left);
printf("%i ", root->data);
print(root->right);
}
假设你想在下面的树中添加 1
5
/ \
2 8
您的代码有一个光标指针。
那个游标指针指向 5,然后是 2,然后是 NULL。
当它达到 NULL 时,你分配新的内存,你的光标指向那个新的内存。
就是这样。你还没有做出你想做的事。
光标指针不是树的一部分。它只是一个用于访问树节点的变量。
现在节点 *left 和节点 *right 是树的一部分,这些节点是必须分配内存的节点。
您的问题的一种解决方案是以下代码:
void insert (node **root, int n){
node *cursor = *root;
while (cursor != NULL){
if (n <= cursor->data){
cursor = *(root=&cursor->left);
printf("left\n");
}else if (cursor->data < n){
cursor = *(root=&cursor->right);
printf("right\n");
}else {
printf("Invalid data in the tree.\n");
return;
}
}
*root = malloc(sizeof(node));
cursor=*root;
cursor->data = n;
cursor->left = NULL;
cursor->right = NULL;
}
int main(void){
node *root = NULL;
insert (&root, 1);
}
进一步改进:
void insert (node **root, int n){
node *cursor = *root;
while (cursor != NULL) cursor=*(root=(n<cursor->data)?&cursor->left:&cursor->right);
cursor=*root=malloc(sizeof(node));
cursor->data = n;
cursor->left = NULL;
cursor->right = NULL;
}
int main(void){
node *root = NULL;
insert (&root, 1);
}