简体   繁体   中英

Inserting a node into a binary search tree in C++

I'm attempting to build a binary search tree and then do a horizontal inorder print with the left most node as the first node displayed. Also, preceding each node is its depth (distance from root) as well as a tilde to help visualize the tree itself. Conceptually my code seems to be correct, but for whatever reason I can't seem to get it to build the tree properly. I figure that the error is most likely in my insert function, but I can't seem to locate it.

Any suggestions or ideas would be extremely helpful!

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;

typedef struct treeNode {

    treeNode *leftChild;
    treeNode *rightChild;
    int data;
} treeNode;


void printTree(treeNode*);
int getNodeDepth(treeNode*);
treeNode* insert(treeNode*, int);
treeNode* createNewNode(int);

int main()
{


    //read in file here



    treeNode *root = NULL;

    root = insert(root, 8);
    root = insert(root, 1);
    root = insert(root, 90);
    root = insert(root, 3);
    root = insert(root, 80);
    root = insert(root, 6);
    root = insert(root, 83);

    printTree(root);

    return 0;
}


/*
 Purpose: Constructs a new node for the tree.
 Inputs:  The data for the node.
 Outputs: returns the new node
 */
treeNode* createNewNode(int data)
{
    treeNode *newNode = new treeNode;
    newNode->data = data;
    newNode->leftChild = NULL;
    newNode->rightChild = NULL;
    return newNode;
}

/*
 Purpose: Calculates the depth of a given node using recursion.
 Inputs:  The node to check the depth on.
 Outputs: returns the depth
 */
int getNodeDepth(treeNode *node)
{
    if (node == NULL)  // tree doesn't exist
        return(0);

    return(1 + max(getNodeDepth(node->leftChild), getNodeDepth(node->rightChild)));
}


/*
 Purpose: Inserts a node into the tree.
 Inputs:  The node to be inserted and the data for the node.
 Outputs: returns the inserted node
 */
treeNode* insert(treeNode *node, int data)
{
    if (node == NULL)
        return createNewNode(data);
    else
    {
        if (data <= node->data)
        {
            node->leftChild = insert(node->leftChild, data);
        }
        else
        {
            node->rightChild = insert(node->rightChild, data);
        }
        return node;
    }
}


/*
 Purpose: Prints the BST in a horizontal inorder format.
 Inputs:  The root node.
 Outputs: nothing
 */
void printTree(treeNode *node)
{
    if (node == NULL)
        return;
    printTree(node->leftChild);
    cout << "(" << (getNodeDepth(node)-1) << ") ";
    for (int i=0; i<(getNodeDepth(node)-1); i++)
        cout << "~";
    cout << node->data << endl;
    printTree(node->rightChild);
}

The current output is as follows:

(2) ~~1
(1) ~3
(0) 6
(3) ~~~8
(1) ~80
(0) 83
(2) ~~90

Obviously it can't have two roots (ie 6 and 83). Thanks!

For those in the future who wish for a correct implementation of the answer to my original question here is the refactored code that I came up. I decided to take an OOP approach and modified the insert and getNodeDepth function to appropriately work.

//
//  Binary Search Tree
//

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;

// binary search tree
class BST {

private:
    typedef struct treeNode {
        treeNode *leftChild;
        treeNode *rightChild;
        int data;
    } treeNode;

    treeNode *root;

public:
    //Constructor
    BST() { root = NULL; }

    /*
     Purpose: Constructs a new node for the tree.
     Inputs:  The data for the node.
     Outputs: returns the new node
     */
    treeNode* createNewNode(int data)
    {
        treeNode *newNode = new treeNode;
        newNode->data = data;
        newNode->leftChild = NULL;
        newNode->rightChild = NULL;
        return newNode;
    }

    //Check if the tree is empty
    bool isEmpty() const { return root==NULL; }

    /*
     Purpose: Calculates the depth of a given node using recursion.
     Inputs:  The node to check the depth on and the node to check the depth from.
     Outputs: returns the depth
     */
    int getNodeDepth(treeNode *node, treeNode *from)
    {
        if (node == from)
            return 0;
        else if (node->data < from->data)
            return getNodeDepth(node, from->leftChild) + 1;
        else
            return getNodeDepth(node, from->rightChild) + 1;
    }


    /*
     Purpose: Inserts a node into the tree.
     Inputs:  The data for the node.
     Outputs: none
     */
    void insert(int newData)
    {
        treeNode* t = createNewNode(newData);
        treeNode* parent;
        parent = NULL;


        if(isEmpty())   //check if tree exists or not
            root = t;
        else {
            //Note: ALL insertions are as leaf nodes
            treeNode* curr;
            curr = root;
            // Find the Node's parent
            while(curr)
            {
                parent = curr;
                if (t->data > curr->data)
                    curr = curr->rightChild;
                else
                    curr = curr->leftChild;
            }

            if ((t->data) < (parent->data))
                parent->leftChild = t;
            else
                parent->rightChild = t;
        }

    }


    /*
     Purpose: Prints the BST in a horizontal inorder format.
     Inputs:  The root node.
     Outputs: nothing
     */
    void printTree(treeNode *node)
    {
        if (node == NULL)
            return;
        printTree(node->leftChild);
        cout << "(" << getNodeDepth(node, root) << ") ";
        for (int i=0; i<getNodeDepth(node, root); i++)
            cout << "~";
        cout << node->data << endl;
        printTree(node->rightChild);
    }

    //Getter for private member variable root
    void printInorder()
    {
        printTree(root);
    }

};

int main()
{
    // read file in here

    BST temp;

    temp.insert(8);
    temp.insert(1);
    temp.insert(90);
    temp.insert(3);
    temp.insert(80);
    temp.insert(6);
    temp.insert(83);

    temp.printInorder();

    return 0;
}

The correct output looks as follows with 8 as the root:

(1) ~1
(2) ~~3
(3) ~~~6
(0) 8
(2) ~~80
(3) ~~~83
(1) ~90

Hope this helps!

In the first you shouldn't write treeNode twice

typedef struct {
    treeNode *leftChild;
    treeNode *rightChild;
    int data;
} treeNode;

In the second you create a memory leak:

treeNode *root = new treeNode;
root = NULL;

You should write:

treeNode *root = NULL;

Obviously it can't have two roots (ie 6 and 83). Thanks!

6 and 83 aren't roots. 8 is a root. So your program gave right answer.

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