YONAH GRAPHICS
YONAH GRAPHICS

Reputation: 19

How do I traverse a tree in-order and just get one value at a time instead of all values in C++

I'm trying to traverse a binary tree inorder and the problem I'm trying to solve requires me to return one value at a time. The problem with binary tree traversal is that you get everything at once using recursion.Don't get me wrong, I want everything but not at once. What I tried implementing an array to store every value and then loop through and get each value. But this too does not seem to work, CPP is complaining that "undefined reference to `IPAddressAnalyzer::nodesArray'"

Here's a snippet of my code:

struct node
{
    int address;
    int count;
    node* left;
    node* right;
};


class IPAddressAnalyzer{

private:
    node* root;
    static node *nodesArray;
    int arrayIndex = 0;
    void destroy_tree(node *leaf);
    void insert(int ip, int count, node *leaf);
    void inorder_print(node *leaf);

And here's where I'm trying to use the array:

void IPAddressAnalyzer::inorder_print(node* leaf)
{

    if(leaf != NULL)
    {
        inorder_print(leaf->right);
        nodesArray[arrayIndex].address = leaf->address;
        nodesArray[arrayIndex].count = leaf->count;
        updateArrayIndex();
        inorder_print(leaf->left);
    }
}

Here's where I create the array, access the elements in the array and try to write to a file.

 //Create the array
    tree->createArray(intCounter);
    tree->inorder_print();
    //Traverse tree and write to a file
    int rank =1;
    int counter = 0;
    int valueHolder = 0;
    int nodeIndex = 0;
    while (rank<=n){
        node element = nodesArray[nodeIndex];
        printf("Popped ip: %s count: %d\n", IPAddressToString(element.address), element.count);
        if(counter == 0) {
            fprintf(outFileStream, "%d, %s, %d\n", rank, IPAddressToString(element.address), element.count);
            valueHolder = element.count;
            counter++;
        }
        else if(element.count == valueHolder)
        {
            fprintf(outFileStream, "%d, %s, %d\n", rank, IPAddressToString(element.address), element.count);
        }
        else{
            rank++;
            if(rank>n)
                break;
            fprintf(outFileStream, "%d, %s, %d\n", rank, IPAddressToString(element.address), element.count);
            valueHolder = element.count;
        }
        nodeIndex++;
    }

Please note that I set the size of the array size in the main function before I use it.

Or, to put it simply, here's an example of what I want;

#include <iostream>

using namespace std;


struct node
{
    int value;
    node *left;
    node *right;
};

class btree
{
public:
    btree();
    ~btree();

    void insert(int key);
    void destroy_tree();
    void inorder_print();
private:
    void destroy_tree(node *leaf);
    void insert(int key, node *leaf);
    void inorder_print(node *leaf);

    node *root;
};


btree::btree()
{
    root = NULL;
}

btree::~btree()
{
    destroy_tree();
}

void btree::destroy_tree(node *leaf)
{
    if(leaf != NULL)
    {
        destroy_tree(leaf->left);
        destroy_tree(leaf->right);
        delete leaf;
    }
}

void btree::insert(int key, node *leaf)
{

    if(key < leaf->value)
    {
        if(leaf->left != NULL)
        {
            insert(key, leaf->left);
        }
        else{
            leaf->left = new node;
            leaf->left->value = key;
            leaf->left->left = NULL;
            leaf->left->right = NULL;
        }
    }
    else if(key >= leaf->value)
    {
        if(leaf->right != NULL)
        {
            insert(key, leaf->right);
        }
        else
        {
            leaf->right = new node;
            leaf->right->value = key;
            leaf->right->right = NULL;
            leaf->right->left = NULL;
        }
    }

}

void btree::insert(int key)
{
    if(root != NULL)
    {
        insert(key, root);
    }
    else
    {
        root = new node;
        root->value = key;
        root->left = NULL;
        root->right = NULL;
    }
}

void btree::destroy_tree()
{
    destroy_tree(root);
}

void btree::inorder_print()
{
    inorder_print(root);
    cout << "\n";
}

void btree::inorder_print(node *leaf)
{
    if(leaf != NULL)
    {
        inorder_print(leaf->left);
        cout << leaf->value << ",";
        inorder_print(leaf->right);
    }
}


int main(){

    //btree tree;
    btree *tree = new btree();

    tree->insert(10);
    tree->insert(6);
    tree->insert(14);
    tree->insert(5);
    tree->insert(8);
    tree->insert(11);
    tree->insert(18);

    tree->inorder_print();
    delete tree;
}

This produces the following output at once:

5,6,8,10,11,14,18, 

How can I get 5, then 6, then 8 etc, but each at a time, instead of all at once? Any help offered will be appreciated!

Upvotes: 0

Views: 187

Answers (1)

G. Sliepen
G. Sliepen

Reputation: 7973

CPP is complaining that "undefined reference to IPAddressAnalyzer::nodesArray"

This is probably because nodesArray is a static member variable, but you never declared storage for it. In some .cpp file, preferably one related to IPAddressAnalyzer, you should add the following line:

node *IPAddressAnalyzer::nodesArray;

But maybe just making it a non-static member would be even better.

I suggest you make use of the standard library instead of implementing your own tree structure, and use std::map and/or std::set instead. Your example of what you want can be rewritten like so:

#include <iostream>
#include <set>

int main(){
    std::set<int> tree;

    tree.insert(10);
    tree.insert(6);
    tree.insert(14);
    tree.insert(5);
    tree.insert(8);
    tree.insert(11);
    tree.insert(18);

    for (auto &element: tree) {
        std::cout << element << ',';
    }

    std::cout << '\n';
}

Upvotes: 1

Related Questions