我有一个封装在带有嵌套节点的类中的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);}
};
当我插入说22
,11
,33
然后打印它时,它只显示22
,始终是根节点。
答案 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);
}