在下面的代码中,我为二叉树编写了一个插入函数。但是在每次调用之后它都不会向树中插入任何节点。我检查了算法是否在二叉树中插入。我认为有一些指针问题,但无法弄清楚为什么会发生这种情况。对于更改指针或在c ++中用另一个指针赋值的函数是否有任何限制?
//binary tree implementation
#include<iostream>
#include<queue>
using namespace std;
//node class with a constructor
struct NODE {
int data;
NODE *lc,*rc;
NODE() {
lc=rc=NULL;
}
};
//tree class with a constructor
struct TREE {
NODE *root;
TREE() {
root = NULL;
}
};
//insertion in a binary tree
//uses queue to keep track of nodes level wise
void insertNode(NODE *r, int key) {
NODE *newNode = new NODE; //getting a new node
newNode->data = key; //setting the value of the node to key
if(!r) { //if r is NULL
//then this is where the new node to be inserted
r = newNode;
return;
}
queue<NODE*> q; //Creating a queue of NODE* to store the
q.push(r); //node at each level ,push r to the queue.
while(!q.empty()) { //Using a level order traversal
//to insert a node to the binary tree.
NODE *temp = q.front(); //And inserting the element wherever we
q.pop(); //found the node whose left or right child
if(temp->lc) //is NULL
q.push(temp->lc); ///If temp has a left child then push it
else { ///into the queue
///else insert the node here
temp->lc = newNode;
return;
}
if(temp->rc) ///If temp has a right child the push it
q.push(temp->rc); ///into the queue
else { ///else insert the node here
temp->rc = newNode;
return;
}
}
}
//inorder traversal of the tree
void inorder(NODE *r) {
if(r) {
inorder(r->lc);
cout<<r->data<<" ";
inorder(r->rc);
}
}
int main() {
TREE t;
insertNode(t.root,5); //inserting 5 to the tree t
insertNode(t.root,10); //inserting 10 to the tree t
insertNode(t.root,15); //inserting 15 to the tree t
inorder(t.root); ` //Now traversing the tree.
///**But after each insertion root of
///tree t is still empty.
///it means the pointer is not being
///changed by the insertionNode fn
///but cant figure this out
return 0;
}
答案 0 :(得分:1)
以下是代码的相关部分:
void insertNode(NODE *r, int key)
{
r = newNode; //inserted
return;
}
您的参数是您传递的指针的副本。赋值会更改该副本,但不会更改该函数的参数。然后,return
立即销毁该副本。
将参数更改为引用以修复:
void insertNode(NODE *&r, int key)
{
r = newNode; //inserted
return;
}
更好的是,由于您的函数仅在TREE
的根节点指针上调用,因此通过引用传递TREE
。
更好的是,由于树插入属于树,因此使该函数成为TREE
的成员函数。然后树将作为隐式this
传递,您可以直接访问root
。而且你也有更好的界面。
答案 1 :(得分:1)
&#34;对于更改指针或在c ++中使用另一个指针赋值的函数是否有任何限制? &#34;
是的,对功能参数的范围有限制(这也适用于c函数参数)。当你调用这段代码时
insertNode(t.root,5);
t.root
等于NULL
,并且正确执行了对新分配的NODE
的分配。但是您正在更改调用insertNode()
的指针的本地副本,因为指针参数r
是按值传递的
void insertNode(NODE *r, int key) {
NODE *newNode = new NODE; //getting a new node
newNode->data = key; //setting the value of the node to key
if(!r) {
r = newNode; // <<<<<<<
return;
}
// ...
并且新创建的节点永远不会写回t.root
。
更改您的函数签名以获取对该指针的引用
void insertNode(NODE*& r, int key) {
// ^
因此它实际上会改变传递给该函数的变量。这将解决主要问题。
虽然我必须同意@tadman's comment但为insertNode()
或inorder()
提供免费功能真的很奇怪。这些实际上应该是TREE
的非静态类成员函数。