Sal So
Sal So

Reputation: 15

Can't display binary search tree C++

I tried creating a binary search tree, using youtube and examples from my professor to help, but display in Driver.cpp doesn't show any node of the tree except "null" (which was intended to represent nullptr). I think it's because my "root" remains as nullptr, even though I've inserted a new node. The output should be "23 null null". Sorry if the codes aren't short and optimized, I want to make things clear for myself when I reread them later.

P.S.: I've deleted some unfinished functions in the code posted here so there might be minor mistakes

//Driver.cpp
#include <iostream>
#include "Overall Tree.h";
using namespace std;

int main()
{
    BinaryTree tree_1;

    tree_1.insertNode(23);

    tree_1.display();

    return 0;
}
//Overall Tree.h
#include <iostream>
using namespace std;

class BinaryTree
{
    struct Node
    {
        int data; 
        Node* left;
        Node* right;
    };

private:
    Node* root;

public:
    // Constructors and Destructors
    BinaryTree();

    //traversal functions
    void preOrder();
    void inOrder();
    void postOrder();
    void preOrderTraverse(Node*);
    void inOrderTraverse(Node*);
    void postOrderTraverse(Node*);

    //display function
    void display();

    //insert functions
    void insertNode(int);
    void insert(Node*, Node*);
};

BinaryTree::BinaryTree()
{
    root = nullptr;
}

//display traversals
void BinaryTree::display()
{
    cout << "Pre-order traversal: " << endl;
    preOrder();
    cout << endl << endl;

    cout << "In-order traversal: " << endl;
    inOrder();
    cout << endl << endl;

    cout << "Post-order traversal: " << endl;
    postOrder();
}

// traversals
void BinaryTree::preOrder()
{
    preOrderTraverse(root);
}

void BinaryTree::inOrder()
{
    inOrderTraverse(root);
}

void BinaryTree::postOrder()
{
    postOrderTraverse(root);
}

void BinaryTree::preOrderTraverse(Node* root)
{
    if (root != nullptr)
    {
        cout << root->data << " ";
        preOrderTraverse(root->left);
        preOrderTraverse(root->right);
    }
    else
        cout << "null ";
}

void BinaryTree::inOrderTraverse(Node* root)
{
    if (root != nullptr)
    {
        preOrderTraverse(root->left);
        cout << root->data << " ";
        preOrderTraverse(root->right);
    }
    else
        cout << "null ";
}

void BinaryTree::postOrderTraverse(Node* root)
{
    if (root != nullptr)
    {
        preOrderTraverse(root->left);
        preOrderTraverse(root->right);
        cout << root->data << " ";
    }
    else
        cout << "null ";
}

//insert
void BinaryTree::insertNode(int x)
{
    Node* newNode = new Node;
    newNode->data = x;
    newNode->left = nullptr;
    newNode->right = nullptr;

    insert(newNode, this->root);
}

void BinaryTree::insert(Node* newNode, Node* p)
{
    if (p == nullptr)
        p = newNode;
    else
        if (newNode->data < p->data)
            insert(newNode, p->left);
        else if (newNode->data > p->data)
            insert(newNode, p->right);
        else
            cout << "Value already existed in the tree.";
}

Upvotes: 1

Views: 158

Answers (1)

NutCracker
NutCracker

Reputation: 12263

You should pass pointer to pointer to root in your insert function like:

void BinaryTree::insert(Node* newNode, Node** p)
{
    if (*p == nullptr) {
        *p = newNode;
    } else {
        if (newNode->data < (*p)->data) {
            insert(newNode, &(*p)->left);
        } else if (newNode->data > (*p)->data) {
            insert(newNode, &(*p)->right);
        } else {
            cout << "Value already existed in the tree.";
        }
    }
}

and then use this function like:

insert(newNode, &this->root);

Why pointer to pointer?

Because you want modifications of the parameter (in this case p parameter), made in the insert function, to affect the argument which the caller passed in.

EDIT

You can also use reference for this purpose:

void BinaryTree::insert(Node* newNode, Node*& p)
{
    if (p == nullptr) {
        p = newNode;
    } else {
        if (newNode->data < p->data) {
            insert(newNode, p->left);
        } else if (newNode->data > p->data) {
            insert(newNode, p->right);
        } else {
            cout << "Value already existed in the tree.";
        }
    }
}

and then use it like:

insert(newNode, this->root);

I would suggest using reference because of the cleaner syntax IMO.

Upvotes: 5

Related Questions