插入二叉树(不是BST)无法正常工作

时间:2015-05-12 21:00:27

标签: c++ pointers binary-tree

在下面的代码中,我为二叉树编写了一个插入函数。但是在每次调用之后它都不会向树中插入任何节点。我检查了算法是否在二叉树中插入。我认为有一些指针问题,但无法弄清楚为什么会发生这种情况。对于更改指针或在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;
}

2 个答案:

答案 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的非静态类成员函数。