在具有全局根的 BST 中插入一个节点
Insert a node in BST with global root
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 全局但插入函数不能无效它必须 return node* value 我能得到一个解释吗?
如果有更好的方法请分享(其实我想把insert做成void类型)
此致,
您编写 insert
的方式要求它始终 returns 它修改或创建的节点。这确保 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
的引用,所以也会更新。
- 在随后的 insert 调用中,您将沿着树下降,直到到达节点 N,您必须在该节点进一步下降,但子节点为 nullptr。当您现在下降时,
localRoot
绑定到 N->left
或 N->right
,第一个子句将再次用指向新创建的节点的指针覆盖该值。
如果默认参数对你来说太神奇了,拆分成两个函数:
void insert_helper(int item, node*& localroot) {
// as above
}
void insert(int item) {
insert_helper(item, root);
}
你的函数的 return 类型 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;
}
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 全局但插入函数不能无效它必须 return node* value 我能得到一个解释吗?
如果有更好的方法请分享(其实我想把insert做成void类型)
此致,
您编写 insert
的方式要求它始终 returns 它修改或创建的节点。这确保 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
的引用,所以也会更新。 - 在随后的 insert 调用中,您将沿着树下降,直到到达节点 N,您必须在该节点进一步下降,但子节点为 nullptr。当您现在下降时,
localRoot
绑定到N->left
或N->right
,第一个子句将再次用指向新创建的节点的指针覆盖该值。
如果默认参数对你来说太神奇了,拆分成两个函数:
void insert_helper(int item, node*& localroot) {
// as above
}
void insert(int item) {
insert_helper(item, root);
}
你的函数的 return 类型 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;
}