简体   繁体   中英

Binary Search Tree Printing Issue

I am working on aa graphical SFML BST menu system. I have test files. Some of them give the expected output but others do not. I have been trying to figure out for a couple of days now and I cant see why. The numbers seem to be inserting into the tree correct, but the inputs that have duplicate numbers seem to breaks the structure of the tree traversal as not all nodes will be outputted. See my code and examples below.

I have a the strut and so on in my .h file which I am pretty sure works fine.

Can anyone tell me why some of these are not traversing all of the nodes?

Input: 1,3,5,6,7,8,9,10 Output: Graph looks as expected and traversal looks like expected.

Input: 3,4,99,3,10,11,10 Output 3,3,10,10 (Not expected)

Input: 10,3,10,24,3,20 Output: 3,3,10,10,24

//Binary Search Tree Program
#include "BinarySearchTree.h"

using namespace std;

sf::CircleShape shape(50);

BinarySearchTree::BinarySearchTree()
{
    root = NULL;

    if (!font.loadFromFile("font.ttf"))
        cout << "Error loading font!";
}


void BinarySearchTree::loadFile(int num) {
    data.clear();
    string s = to_string(num);
    string text;
    string temp; // Added this line
    ifstream file;
    file.open("files/file" + s + ".txt");

    while (!file.eof())
    {
        getline(file, temp);
        text.append(temp); // Added this line
    }

    std::istringstream ss(text);
    std::string token;
    while (std::getline(ss, token, ',')) {
        std::cout << token << ',';
        std::string myString = token;
        int value = atoi(myString.c_str()); //value = 45 
        data.push_back(value);
    }
}

void BinarySearchTree::passToinsert()
{
    for (std::vector<int>::iterator it = data.begin(); it != data.end(); ++it) {
        insert(*it);
        //cout << *it;
    }
}


void BinarySearchTree::insert(int d)
{
    tree_node* t = new tree_node;
    tree_node* parent;
    t->data = d;
    t->left = NULL;
    t->right = NULL;
    parent = NULL;

    // is this a new tree?
    if (isEmpty()) root = t;
    else
    {
        //Note: ALL insertions are as leaf nodes
        tree_node* curr;
        curr = root;
        // Find the Node's parent
        while (curr)
        {
            parent = curr;
            if (t->data > curr->data) curr = curr->right;
            else curr = curr->left;
        }

        if (t->data < parent->data) {
            parent->left = t;
            cout << "L-" << t->data<<endl;
        }
        else {
            parent->right = t;
            cout << "R-" << t->data << endl;

        }
    }
}


void BinarySearchTree::print_inorder()
{
    inorder(root);
}

void BinarySearchTree::inorder(tree_node* p)
{
    if (p != NULL)
    {
        if (p->left) inorder(p->left);
        cout << " " << p->data << " ";
        if (p->right) inorder(p->right);
    }
    else return;
}

void BinarySearchTree::print_postorder()
{
    postorder(root, 100,0,0,0,0);
}


void BinarySearchTree::postorder(tree_node* p, int indent, int leftNodeCount, int rightNodeCount, int left, int right)
{

    if (p != NULL) {

        if (left = 1) {
            std::string s = std::to_string(p->data);

            nodes[nodeCount].setFont(font);
            nodes[nodeCount].setFillColor(sf::Color::White);
            nodes[nodeCount].setString(s);
            nodes[nodeCount].setPosition(sf::Vector2f(indent, 80 + (leftNodeCount * 80)));
            nodeCount++;
            leftNodeCount++;
        }
        else if (right = 1) {
            std::string s = std::to_string(p->data);

            nodes[nodeCount].setFont(font);
            nodes[nodeCount].setFillColor(sf::Color::White);
            nodes[nodeCount].setString(s);
            nodes[nodeCount].setPosition(sf::Vector2f(indent, 80 + (rightNodeCount * 80)));
            nodeCount++;
            rightNodeCount++;
        }
        else {
            std::string s = std::to_string(p->data);

            nodes[nodeCount].setFont(font);
            nodes[nodeCount].setFillColor(sf::Color::White);
            nodes[nodeCount].setString(s);
            nodes[nodeCount].setPosition(sf::Vector2f(indent, 80 + (nodeCount * 80)));
            nodeCount++;
        }


        if (p->right) {
            postorder(p->right, indent + 80, leftNodeCount, rightNodeCount,left=0,right=1);
        }
        if (p->left) {
            postorder(p->left, indent - 80, leftNodeCount, rightNodeCount, left = 1, right = 0);
        }
    }
}

//Draw sub menu heading text and options to screen
void BinarySearchTree::drawNodes(sf::RenderWindow &window)
{
    window.clear();

    for (int i = 0; i < 10; i++)
    {
        window.draw(nodes[i]);
    }

    window.display();
}

In fact, numbers are not inserted into the tree correctly. The main problem is located in the insert() function of the class BinarySearchTree .

In the while-loop while (curr) , the switch between left and right is managed by the if-condition if (t->data > curr->data) , assuming that case t->data == curr->data is connected to the left side.

After the while-loop, the switch between left and right is managed by the if-condition if (t->data < parent->data) , assuming that case t->data == parent->data is connected to the right side. And not to the left side !!!

Solution - just swap the switch condition inside the while-loop as follow.

if (t->data < curr->data) {
    curr = curr->left;
}
else {
    curr = curr->right;
}

Instead of:

if (t->data > curr->data) curr = curr->right;
else curr = curr->left;

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