在 C 中为二叉树实现 'insert' 函数

Implementing 'insert' function for binary tree in C

我正在尝试在 C 中为二叉树实现通常的 'insert' 函数,但我无法弄清楚我的代码哪里有问题(但肯定是错误的,因为它没有没用...).

谁能帮我找出我做错了什么?

#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);

}

您正在分配给 cursor,而 cursor->leftcursor->right 未分配。 确保新分配的节点由 cursor->leftcursor->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;

}

您需要保留对之前 cursor 的引用。你需要找到cursor->data为空的地方;但是,如果您要查找 cursor 本身为 null 的位置,它不会为您做任何事情,因为 cursor 不是对前一个 cursor->data 的引用,而是一个副本:当您更改 cursor,您的结构没有任何变化。

您的代码:

#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);
}