【问题标题】:Implementing 'insert' function for binary tree in C在 C 中实现二叉树的“插入”函数
【发布时间】:2015-01-02 04:56:13
【问题描述】:

我正在尝试在 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);

}

【问题讨论】:

  • 哦,对了,我在函数中添加了一些 printf,正在尝试调试。
  • 有什么问题?
  • 您说“它不起作用”,您能告诉我们如何它不起作用吗?您是否收到编译错误(或警告)?它会导致运行时崩溃吗?行为或输出是否意外?您是否尝试过运行或单步调试调试器?将来请包括所有此类详细信息。
  • 但是,在您的情况下,很容易看出问题所在,您实际上并没有在树中的任何地方 插入 新节点。您只是分配了一个新节点,但实际上并没有将它添加到树中。
  • 很抱歉它不起作用,因为当我打印树时,我没有得到我插入的值——我知道打印功能是正确的

标签: c tree insert binary-tree


【解决方案1】:

您正在分配给cursor,而cursor-&gt;leftcursor-&gt;right 未分配。 确保cursor-&gt;leftcursor-&gt;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;

}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您的代码:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2015-02-14
        • 1970-01-01
        • 1970-01-01
        • 2017-12-16
        • 1970-01-01
        • 2020-08-26
        相关资源
        最近更新 更多