C++箭头运算符->使用疑问?BST插入逻辑异常导致遍历问题求解
ptr->left=insert(ptr->left, item) with ptr = ptr->left; ptr = insert(ptr, item) break my BST in-order traversal? I have a simple Binary Search Tree (BST) implementation with only insert and in-order traversal functions:
struct Node{ int data; Node* left; Node* right; }; Node* create(int data){ Node* node = new Node; node -> data = data; node->left=node->right=NULL; return node; } Node* insert(Node* ptr,int item); void inorder(Node* ptr); int main(){ Node* root = NULL; int temp,ch; root = insert(root, 10); root = insert(root, 20); root = insert(root, 30); inorder(root); cout<<endl; } Node* insert(Node* ptr,int item){ if(ptr==NULL){ cout<<"Inserted "<<item<<endl; return create(item); } if(item<ptr->data){ // ptr = ptr->left; // ptr = insert(ptr, item) ptr->left=insert(ptr->left, item); } else{ // ptr=ptr->right; // ptr = insert(ptr, item) ptr->right=insert(ptr->right, item); } return ptr; } void inorder(Node* ptr){ if(ptr==NULL) return; inorder(ptr->left); cout<<ptr->data<<" "; inorder(ptr->right); }
When I replace ptr->left=insert(ptr->left, item) with ptr = ptr->left; ptr = insert(ptr, item) (and do the same for the right side), the in-order traversal only prints the last inserted element. Is this a C++ language issue, or am I misunderstanding some core concept here?
This is a misunderstanding of how pointers work in C++, not a language issue
Let's break down why your modified code fails, and why the original approach works:
How the correct code works
The line ptr->left = insert(ptr->left, item) does two critical things:
- It calls
insertwith the current value ofptr->left(which might beNULLif there's no left child yet). - It takes the return value of
insert(either the newly created node, or the existing child if the item was already present) and directly updates theleftmember of the currentptrnode. This maintains the link between the parent node and its left subtree.
Why your modified code breaks the tree
When you use ptr = ptr->left; ptr = insert(ptr, item), you're only modifying the local ptr variable inside the insert function, not the actual parent node's pointer member:
ptr = ptr->leftchanges the localptrto point to the current left child (orNULLif there isn't one).ptr = insert(ptr, item)updates this localptrto point to the newly created node, but this doesn't affect the original parent node'sleftmember— that parent'sleftis stillNULL(or whatever it was before).- To make matters worse, since your
insertfunction returns this localptr, each time you callroot = insert(root, ...)inmain, you're overwritingrootto point to the last inserted node instead of maintaining the root of the full tree. All previous nodes are effectively lost because they're never linked to the rest of the tree.
For example, when inserting 20 after 10:
- The original code updates
root->rightto point to the new 20 node, keeping it connected to the root. - Your modified code changes the local
ptr(which started asroot) to point toroot->right(NULL), then sets that localptrto the new 20 node. Butroot->rightis still NULL, and the function returns the localptr(20), sorootbecomes 20. Then inserting 30 repeats this process, overwritingrootto 30— leaving you with only a single node, hence the in-order traversal only prints 30.
Key takeaway
In C++, when you want to modify a pointer that's a member of a struct/class (like Node::left), you need to assign directly to that member variable. Changing a local pointer variable inside a function doesn't alter the original struct's members— it just changes where that local variable points.
内容的提问来源于stack exchange,提问作者Rajan

