bst insert recursion c ++

时间:2014-12-21 18:13:16

标签: c++ recursion binary-search-tree

我有一个封装在带有嵌套节点的类中的bst。

当我尝试插入然后打印树时,类的根属性似乎没有更新, 即使我确实更新了它。

void bst::insert(int key,node* temp)
{
  if(temp==NULL)
  {
      node* ptr=getnewnode(key);
      if(root==NULL)
        root=ptr;
       else
       {
         temp=ptr;
         return ;
       }
  }
     if(key<temp->key)
      insert(key,temp->left);
     if(key>temp->key)
      insert(key,temp->right);
}

class bst
{
typedef struct node
{
int key;
node* left;
node* right;
}node;
node* root; 
void insert(int key,node* temp);
public:
inline void _insert(int key){insert(key,root);}   
};

当我插入说221133然后打印它时,它只显示22,始终是根节点。

2 个答案:

答案 0 :(得分:1)

我想当你从课堂外调用insert()时,NULL被提供作为第二个参数,因为root是私有的。

问题1:

如果您insert(22, NULL)第一个节点作为傻瓜被添加到您的bst:

  ... 
     if(root==NULL)   // yes, the bst is still empty:  
        root=ptr;     // so root is set to the new node that was created
     else {...}       // and this bloc is ignored 
  }
  if(key<temp->key)   // OUCH !!!! temp is not initalized here                        
  ...                 

你冒这个内存损坏或段错误的风险!

问题2:

如果您随后insert(11, NULL)发生了什么:

  ... 
      if(root==NULL)   // No, the bst has already a root  
      else {           // so the else block is executed
          temp = ptr;  // you prepare to do something with temp
          return;      // WHY ??  You end the function an return without having done anything 
  ...  

问题3:

假设你删除了return语句,那么请记住你刚刚覆盖了temp。代码将继续如下:

 if(key<temp->key)     // this is false, because temp points to the new node, which has the seme key (temp->key==key) !
 if(key>temp->key)     // this is false, for the same reason 

所以没有一个递归插入完成!

<强>解决方案:

我建议你这样:

void bst::insert(int key,node* temp)
{
    if(temp==NULL) {
       if(root==NULL) {
           root=getnewnode(key);
           return; 
       }
       else 
           temp=root;  // we now start browsing the tree with root 
    }
    if(key<temp->key) {
        if (temp->left==NULL) 
           temp->left = getnewnode(key);  
       else insert(key,temp->left);
    }
    else if(key>temp->key) {
        if (temp->right==NULL) 
           temp->right = getnewnode(key);
       else insert(key,temp->right);
    }
    else if (key==temp->key) { 
        // to do:  what happens if key==temp->key 
    }
}

当再次插入现有密钥时,不清楚预期的内容。由您根据您的期望进行调整。

编辑:使用包装器的解决方案:

在您使用包装器进行编辑后,我建议您使用以下变体:

void bst::insert(int key,node*& temp)  // attention:  change of signature !!!
{
    if(temp==NULL) {  // either root is null or we have reached a null leave
       temp = getnewnode(key);    // temp is a reference to original root or node pointer.  It can be changed directly with this statement 
       }
    else if(key<temp->key) 
       insert(key,temp->left);
    else if(key>temp->key) 
       insert(key,temp->right);
    else if (key==temp->key) { 
        // to do:  what happens if key==temp->key 
    }
}

答案 1 :(得分:0)

我仍然不确定我在这里做错了什么,但现在代码适用于以下更改。 //包装函数

void insert(int key)
{
   node * temp=_insert(key,root);
   preorder(root);
}

node* bst::insert(int key,node* temp)
{
 if(root==NULL)
  {
      node* ptr=getnewnode(key);
        root=ptr;
        return root;
  }
   if(temp==NULL)
  {
       node* ptr=getnewnode(key);
       return ptr;
  }
     if(key<temp->key)
      temp->left=insert(key,temp->left);
     if(key>temp->key)
      temp->right=insert(key,temp->right);
}