【问题标题】:malloc in pointer received as argument作为参数接收的指针中的 malloc
【发布时间】:2016-06-14 07:03:03
【问题描述】:

我正在实现一个二叉搜索树,但由于某些原因我无法添加节点

我的:输入是:

a.value = 5;
add_bst_node(&t,a); 

我的结构:

typedef struct BST_node{
 entity value;
 struct BST_node* left;
 struct BST_node* right;
}BST_node;

typedef struct BST_tree{
 BST_node* root;
}BST_tree;

我添加节点的代码:

void add_bst_node2(BST_node* root,entity* e){
 if(!root){
  root = (BST_node*)malloc(sizeof(BST_node));
  root->value = *e;
  root->left = NULL;
  root->right = NULL;
  return;
 }
 else if(great_than(&root->value,e))
  add_bst_node2(root->left,e);
 else
  add_bst_node2(root->right,e);
 }

 void add_bst_node(BST_tree* t,entity e){
  add_bst_node2(t->root,&e);
  printf("%d\n",t->root==NULL);
 }

谁能解释我为什么不能添加节点?

【问题讨论】:

  • root 是函数 add_bst_node2 中的局部变量。将其设置为一个值仅在函数范围内(运行时)有效。您应该调用add_bst_node2(&t->root...),将函数原型更改为BST_node** root,并设置*root = ...
  • 尝试将void add_bst_node2(BST_node* root,entity* e)更改为void add_bst_node2(BST_node* &root,entity* e)
  • @LPs:那么将root 作为输入参数传递有什么意义呢?
  • @GauravSehgal:问题被标记为 C,而不是 C++
  • @barakmanos。对不起,我的错。

标签: c malloc binary-search-tree


【解决方案1】:

除了没有将双指针传递给add_bst_node2() 中的BST_node(即BST_node**),如 cmets 中所述,您也没有正确实现该函数。

您的实现从未真正添加节点,而是进入无限递归。

在这里你可以找到一些关于 BST 的简洁理论 - http://www.zentut.com/c-tutorial/c-binary-search-tree/

这是对您的代码的未经测试的更正。 请注意,这里我们将指针传递给 BST_tree 而不是 BST_node

void add_bst_node2(BST_tree* tree,entity* e){
    if(!tree->root){
        /* If the binary search tree is empty, we just create a root node */
        tree->root = bst_create_node(e);
        return;
    }

    int is_left  = 0;
    BST_node* current_node = tree->root;
    BST_node* prev   = NULL;

    /* Traverse the tree until we find the proper position for the new node.
     * The position is denoted by 'current_node'
     */
    while(current_node != NULL) {
        prev = current_node;

        if(greater_than(&current_node->value, e)) {
            is_left = 1;
            current_node = current_node->left;
        } else {
            is_left = 0;
            current_node = current_node->right;
        }
    }

    /* We finally know the position where we should add the new node */
    if(is_left)
        prev->left = bst_create_node(e);
    else
        prev->right = bst_create_node(e);
}

我们介绍另一个用于创建和初始化节点的函数...

BST_node *bst_create_node(entity *e)
{
    BST_node *n = malloc(sizeof(BST_node));

    n->value = *e;
    n->left = NULL;
    n->right = NULL;

    return n;
}

最后我们更改add_bst_node()

void add_bst_node(BST_tree* t,entity e){
    add_bst_node2(t, &e);
    printf("%d\n", t->root==NULL);
}

【讨论】:

    【解决方案2】:

    从表面上看,a 是一个结构 BST_node,而 value 是其中的一个变量。您必须将值传递给函数并在那里处理节点创建,或者传递整个构造的节点并从现有树中指向它。

    【讨论】:

      【解决方案3】:

      第一件事是你放置了一个不必要的结构 BST_tree。你可以用简单的方式来做,比如

                       struct node
                      {
                          int value;
                          node* left;
                          node* right;
                      };
                      struct node* root;
      

      我建议你试试这个代码

              struct node* insert(struct node* r, int data)
              {
                if(r==NULL) // BST is not created created
                {
                     r = (struct node*) malloc(sizeof(struct node)); // create a new node
                     r->value = data;  // insert data to new node
                    // make left and right childs empty
                     r->left = NULL;   
                     r->right = NULL;
                }
               // if the data is less than node value then we must put this in left sub-tree
                else if(data < r->value){ 
                     r->left = insert(r->left, data);
                }
               // else this will be in the right subtree
               else {
                     r->right = insert(r->right, data);
                }
               return r;
         }`
      

      `

      【讨论】:

      • 注意:当人们查看r = (struct node*) malloc(sizeof(struct node)); 时,有一个问题,是否使用了正确的类型?如果代码是r = malloc(sizeof *r);,则不存在正确性问题。第二个当然更容易编码、维护和审查。
      猜你喜欢
      • 2021-11-26
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多