【问题标题】:Binary search tree node insertion二叉搜索树节点插入
【发布时间】:2014-02-03 15:52:26
【问题描述】:

想要在二叉树中插入元素。这段代码有什么问题。我有一个数据结构,左右作为自引用结构,根作为初始化为 NULL 的类型结构的全局变量。

void insert(struct tree_node *root,int data)
{
    if(root == NULL)
    {
        tree_node *new_node = new tree_node();

        new_node->left = NULL;
        new_node->right = NULL;
    }
    else if(root->data > data)
    {
        insert(root->left,data);
    }
    else
    {
    insert(root->right,data);
    }
}

【问题讨论】:

  • 为什么你似乎只使用 C++ 作为其 new 关键字?

标签: c++ data-structures


【解决方案1】:

您在此处提出的代码存在几个问题:

  • 您从未将全局变量设置为“root”。此外,全局变量总是一件坏事(尤其是如果您打算使用线程)。
  • 您永远不会将新条目链接到现有结构。
  • 您从不设置新的条目数据

你或许应该试试这个:

struct tree_node *insert(struct tree_node *root, int data) 
{
  if(root == NULL) {
    struct tree_node *new_node = new tree_node();

    new_node->data = data;
    new_node->left = NULL;
    new_node->right = NULL;

    return new_node;
  } else if(root->data > data) {
    root->left = insert(root->left, data);
  } else {
    root->right = insert(root->right, data);
  }

  return root;
}

你可以调用它

root = insert(root, data);

as shown on this codepad

【讨论】:

  • 这里没有全局变量(可能以前版本的问题有);否则,我喜欢你的回答!
  • 你确实意识到,如果你使用这个函数在树的中间插入一个节点,你实际上会丢失节点......
  • +1:今天没有想清楚......删除了我的答案,因为当我写键盘时,我最后才写了这个:) @pandrei:怎么会这样?
  • 函数中确实没有全局变量,但Elias提到了“root”的全局变量
  • 这里不能丢失节点,插入总是作为叶子执行
【解决方案2】:

**你已经创建了 new_node 但没有给它赋值。所以你不能给它插入一个值。

也可以使用非递归函数插入

void insert_nrec(int m)  //for insert in binary tree
{
node *tmp,*par,*ptr;
ptr=root;
par=NULL;
tmp=NULL;
    while(ptr!=NULL)
    {
        par=ptr;
        if(m<ptr->data)
        {   ptr=ptr->lchild;    }
        else if(m>ptr->data)
        {   ptr=ptr->rchild;    }
        else
            {   
                cout<<"duplicate key found::";
                return;             
            }       

    }
tmp=new node;
tmp->data=m;
tmp->lchild=NULL;
tmp->rchild=NULL;
if(par==NULL)
    {
        root=tmp;
    }   
else if(m<par->data)
    {
        par->lchild=tmp;    
    }
else
    {
        par->rchild=tmp;
    }

}

【讨论】:

  • 您可以通过使用指针到指针来避免重复左/右决策;看我的回答。
【解决方案3】:

您何时将 root 设置为 NULL 以外的任何内容?

一旦你这样做了,你如何真正改变root-&gt;leftright

【讨论】:

    【解决方案4】:

    我只是要重写@TheRealNeo 的漂亮“功能”答案,以便您将其传递给根指针的引用:

    void insert(struct tree_node * &root, int data) 
    {
      if(root == NULL) {
        struct tree_node *new_node = new tree_node();
    
        new_node->data = data;
        new_node->left = NULL;
        new_node->right = NULL;
    
        root = new_node;
      } else if(root->data > data) {
        insert( root->left, data);
      } else {
        insert( root->right, data);
      }
    }
    

    您使用的调用方式

    insert(root, data);

    与函数式相比,它的一个优势是编译器很有可能实际上将递归调用作为“尾递归”进行,即当插入左时,而不是进行递归调用,代码将简单地更改 ' root' 引用来引用 'root->left' 并跳回到函数的开头。

    显式非递归形式不是很清楚,因为它涉及一些指针到指针的东西,但它真的没那么糟糕:

    void insert(struct tree_node * &root, int data) 
    {
      struct tree_node **ptrp = &root;
    
      while(*ptrp != NULL ){
         struct tree_node *np = *ptrp;
         if( np->data > data ){
              ptrp = &np->left;
         }else{
              ptrp = &np->right;
         }
      }
       // new node will be placed at *ptrp, a location
       // currently containing NULL.
    
      struct tree_node *new_node = new tree_node();
    
      new_node->data = data;
      new_node->left = NULL;
      new_node->right = NULL;
    
      *ptrp = new_node;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      相关资源
      最近更新 更多