简体   繁体   中英

Why Is My Binary Tree Overwriting The Leaves Of Its Root?

I've pinpointed my issue to this specific function, it's the helper function for my binary tree. Before this function call there is a node but instead of growing it seemingly just replaces that node. When I look at my code in my head it all makes sense but I can't figure out what I'm doing wrong.

Here is the function that calls add:

void BSTree::Insert(Client &newClient) {
    if (isEmpty())
    {
        Node *newNode = new Node(newClient);
        this->root = newNode;
    }
    else
        add(this->root, newClient);
}

and here is my add() function:

BSTree::Node* BSTree::add(Node *node, Client &newClient) // helper function for Insert()
{
    if (node == nullptr)
        {
            Node *newNode = new Node(newClient);
            //node = newNode; // already tried adding this in
            return newNode;
        }
    if (newClient.clientID < node->pClient->clientID)
        return node->left = add(node->left, newClient); // already tried just returning add()
    else
        return node->right = add(node->right, newClient);
}

Since this is your question, I will explain what your code is doing. Imagine you have a mature binary tree already and you are adding a node to your tree. By the time you reach this line

return node->left = add(node->left, newClient);

Three separate instructions are carried out:

  1. newClient is added to the left branch of node by add().
  2. the left child of node is set to the return value of add().
  3. the right hand side (RHS) of the assignment is returned by the parent function.

The issue is with number 2. If the tree you are adding to is mature already, changing left child of nodes as you're traversing the tree will cause the override effect that you're observing. In fact, the problem goes beyond overwriting leaves. Since you use the new keyword, the overwritten nodes still have allocated heap space, are never deleted and cause a memory leak.

Here are some thoughts to get you on the right direction:

Your insert() function ensures that the first time you call add(), you are not passing nullptr as the first argument. Take advantage of that and ensure nullptr is never passed into add() function by checking for nullptr before you do the recursive call. Change the return type of add() to void. You no longer need to check node is nullptr. Here's some pseudocode to guide you

void add(node, val)
    if val < node.val
        if node.left exists
            add(node.left, val)
        else
            make a new object and set node.left to that object
    else
        if node.right exists
            add(node.right, val)
        else
            make a new object and set node.right to that object

There is a problem with your logic. First of all, there is the insert() method which you should write like this for better understanding:

void BSTree::Insert(const Client &newClient) // use const to prevent modification
{
    if (isEmpty()) { root = new Node(newClient); }
    else { add(this->root, newClient); }
}

This way you are creating a new object at root directly with the help of 'root' pointer in BSTree.

Now, about the add() method. The 'node' you are passing as a parameter is a copy of the pointer variable, so the actual pointer value is not changed. See this:

BSTree::Node* BSTree::add(Node *node, Client &newClient) //logical error

You need to pass the Node* by reference like this using 'Node* &node':

BSTree::Node* BSTree::add(Node* &node, const Client &newClient)

Why is you binary tree overwriting the roots of its leaves? Answer: Your recursive call with return statement is totally wrong.

return node->left = add(node->left, newClient);

The add(node->left, newClient) always returns the address of the leaves, and you are returning this value. It goes for recursive calls until it reaches the leaves place.

Conclusion: Since, there are a lot of bugs, I would suggest you re-write logic again carefully. I hope this helps! :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM