问题描述
struct node{
int data;
struct node*left,*right;
};
node* root; //global root
node* getNode(int item)
{
node* new_node = new node;
new_node->data = item;
new_node->left=new_node->right=NULL;
return new_node;
}
node* insert(node* localroot,int item)
{
if(localroot == NULL){
localroot = getNode(item);
}
else if(item < localroot->data)
localroot->left = insert(localroot->left,item);
else if(item > localroot->data)
localroot->right = insert(localroot->right,item);
root = localroot;
return root; //Why do I have to return root if it is global?
//without this output is wrong
}
void inorder(node* root)
{
if(root != NULL){
inorder(root->left);
std::cout << root->data << ' ';
inorder(root->right);
}
}
void postorder(node* root)
{
if(root != NULL){
postorder(root->left);
postorder(root->right);
std::cout << root->data << ' ';
}
}
int main()
{
insert(root,15);
insert(root,9);
insert(root,2);
insert(root,1);
insert(root,4);
insert(root,18);
std::cout<<"inorder traversal of tree is: ";
inorder(root);
std::cout << "\npostorder: ";
postorder(root);
return 0;
}
通常在main中,我们将插入称为root = insert(root,10);
(其中root在main()内部声明)。
我想声明root全局性,但是insert函数不能为空,它必须返回node *值,我可以对此进行解释。
如果有更好的方法,请共享(实际上我想将insert设为void类型)。
问候
解决方法
您编写insert
的方式要求它始终返回修改或创建的节点。这样可以确保没有子节点的节点上的insert
设置正确的成员(左或右)。
您可以通过传递对要设置的指针的引用来将root
重写为纯命令性的内容:
void insert(int item,node*& localroot = root) {
if (localroot == nullptr) {
localroot = getNode(item);
return;
}
if (item == localroot->data) {
return;
} else if(item < localroot->data) {
insert(item,localroot->left);
} else if(item > localroot->data) {
insert(item,localroot->right);
}
}
要实现的关键点是对localroot
的分配将反映在数据结构中,因此:
- 第一次调用
insert(item)
时,localroot
是对root
的引用,它是一个空指针。因此,第一个子句适用,并且您用新节点覆盖localRoot
。因为localRoot
是对root
的引用,所以它也会被更新。 - 在随后的插入调用中,您将下降树,直到最终到达节点N,在该节点处您必须进一步下降,但子节点为nullptr。当您现在下降时,
localRoot
绑定到N->left
或N->right
,第一个子句将再次使用指向新创建的节点的指针覆盖该值。
如果默认参数对您来说太神奇了,请分成两个函数:
void insert_helper(int item,node*& localroot) {
// as above
}
void insert(int item) {
insert_helper(item,root);
}
,
函数insert
的返回类型意味着您必须通过以下方式调用它
root = insert(root,15);
在您的函数中,这些语句
root = localroot;
return root; //Why do I have to return root if it is global?
//without this output is wrong
错了。
使用函数声明,可以通过以下方式定义函数
node* insert( node* localroot,int item )
{
if ( localroot == NULL ){
localroot = getNode( item );
}
else if ( item < localroot->data )
localroot->left = insert( localroot->left,item );
else if ( item > localroot->data )
localroot->right = insert( localroot->right,item );
return localroot;
}