Search code examples
c++data-structuresbinary-search-tree

Binary Search Tree with Reading File


I am a student studying data structures. Here's my BST code. During the execution of the main function, the output is

1
2
3
4

...and 's' is not output, and is a core dumped. Why is that...?

Here is my code:

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

class Node {
public:
    string data = "";
    Node *par;
    Node *left;
    Node *right;
    Node() : data(""), par(nullptr), left(nullptr), right(nullptr) {}
};

class BST {
public:
    Node *v;

    BST() { v = nullptr; }
    
    Node *parent() const {
        if (v == nullptr)
            return nullptr;
        return v->par;
    }

    Node *left() const { return v->left; }

    Node *right() const { return v->right; }
  
    bool isRoot() const {
        if (v == nullptr)
            return false;
        return v->par == nullptr;
    }

    bool isExternal() const {
        if (v == nullptr)
            return false;
        return v->left == nullptr && v->right == nullptr;
    }

    bool isInternal() const {
        if (v == nullptr)
            return false;
        return v->left != nullptr || v->right != nullptr;
    }
    
    string &data() const { return v->data; }
 
    void addNode(const string &data) {
        Node *newNode = new Node();
        newNode->data = data;
        newNode->par = nullptr;
        newNode->left = nullptr;
        newNode->right = nullptr;
        if (isRoot()) { 
            v = newNode;
            return;
        } else {
            Node *current = v;
            while (true) {
                if (data < current->data) {
                    if (current->left == nullptr) {
                        current->left = newNode;
                        newNode->par = current;
                        return;
                    } else {
                        current = current->left;
                    }
                } else if (data > current->data) {
                    if (current->right == nullptr) {
                        current->right = newNode;
                        newNode->par = current;
                        return;
                    } else {
                        current = current->right;
                    }
                } else {
                    delete newNode;
                    return;
                }
            }
        }
    }

    void printAncestors(Node *node) {
        if (node == nullptr)
            return;
        cout << node->data << endl;
        printAncestors(node->par);
    }

    void clear(Node *node) {
        if (node == nullptr)
            return;
        clear(node->left);
        clear(node->right);
        if (node->par != nullptr) {
            if (node->par->left == node)
                node->par->left = nullptr;
            else if (node->par->right == node)
                node->par->right = nullptr;
        }
        delete node;
    }

    Node *getRoot() const { return v; }
};

int main() {
    BST *inputTree = new BST();
    BST *outputTree = nullptr;

    for (int i = 1; i <= 50; i++) {
        string input = "inputs/input." + to_string(i) + ".txt";
        string output = "outputs/output." + to_string(i) + ".txt";
        ifstream inputFile(input);
        if (!inputFile) {
            cerr << "Failed to open input file: " << input << endl;
            continue;
        }  
        ////////////////////////// this part! //////////////////////////
        string line;
        int lineNumber = 0;
        while (getline(inputFile, line)) {
            lineNumber++;
            cout << lineNumber << endl;
            if (lineNumber >= 4) {
                cout << "s";
                inputTree->addNode(line);
            }
        }
        ////////////////////////// this part! //////////////////////////
        inputFile.close();
        inputTree->printAncestors(inputTree->getRoot());
        inputTree->clear(inputTree->getRoot());
    }
    delete inputTree;
    delete outputTree;
    return 0;
}

Here is part of input file

charlotte philip joe
jesse mary sandra
8
gabriel theresa diane
marie raymond joshua
jesse mary sandra
charlotte philip joe
alexis jose shirley
diana anna kyle
susan james janice
joe ethan isabella

I want to call addNode to add strings to the BST from line 4 of the input to its end.


Solution

  • 's' is not output and is a core dumped. Why is that...?

    s is not output because it is still in the output buffer. If you want to see that output, then output a newline, like this:

                cout << "s" << endl;
    

    Now you will see it in the output.

    As to the core dump. This happens because you deference a null pointer at the following statement:

    if (data < current->data) {
    

    When this executes the first time, current is nullptr, because v is nullptr, and isRoot() returned 0. Your function isRoot checks if there is a node, and that node is the root. Since your tree is empty, there is no such node. But the calling code apparently expects to get in the if block when the tree is empty. So you need to review and correct this.

    Problems like this are quite easy to detect when you use a debugger and set breakpoints in your code and inspect variables.