插入二进制树(非BST)不起作用

insertion in a binary tree ( not BST ) not working

本文关键字:BST 不起作用 二进制 插入      更新时间:2023-10-16

在以下代码中,我为二进制树编写了插入功能。但是在每次调用后,它不会将任何节点插入到树上。我已经检查了该算法是否在二进制树上插入。我认为存在一些指针问题,但无法弄清楚为什么会发生这种情况。对于更改指针或用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;
}

这是代码的相关部分:

void insertNode(NODE *r, int key)
{
   r = newNode;             //inserted
   return;
}

您的参数是您传递的指针的A 复制。作业更改复制,但没有更改为函数的参数。然后,该副本立即被return销毁。

将参数更改为解决此问题的引用:

void insertNode(NODE *&r, int key)
{
   r = newNode;             //inserted
   return;
}

更好,因为您的函数仅在TREE的根节点指针上调用,请通过参考传递该TREE

甚至更好,因为树插入属于树,请使该功能成为TREE的成员函数。然后,将树作为隐式this传递,您可以直接直接访问root

,您也会有一个更好的接口。

"对于更改指针或用C 中的另一个指针分配的功能是否有任何限制? "

是的,函数参数的范围存在限制(这也适用于C函数参数)。当您调用此代码

insertNode(t.root,5);

t.root等于NULL,并且正确执行了针对新分配的NODE的分配。但是您正在更改调用insertNode()的指针的本地副本,因为指针参数r通过Value

传递
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的评论,但对于insertNode()inorder()拥有免费功能真的很奇怪。这些应该是TREE的非静态类成员函数。