Reputation: 19
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
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