BST 插入递归 C++

bst insert recursion c++

本文关键字:C++ 递归 插入 BST      更新时间:2023-10-16

我有一个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,始终是根节点。

我想

当你从类外调用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 
    }
}

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

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