C++ Binary Tree With 3 Values For Struct - c++

So I am attempting to create a binary search tree that stores an ID (T value) an age (int age) and a name (string) per each "bubble" located within the tree and is sorted by the ID.
For some reason, I cannot get my code to correctly store all 3 values as 1 structure per node. Is there something I am doing wrong?
Here's my code.
#ifndef _TREE_GUARD
#define _TREE_GUARD 1
#include <iostream>
#include <math.h>
using namespace std;
template <class T>
struct Node {
T value;
int age;
string name;
Node *left;
Node *right;
Node(T val) {
this->value = val;
}
Node(T val, int age, string name, Node<T> left, Node<T> right) {
this->value = val;
this->age = age;
this->name = name;
this->left = left;
this->right = right;
}
};
template <class T>
class BST {
private:
Node<T> *root;
void addHelper(Node<T> *root, T val) {
if (root->value > val) {
if (!root->left) {
root->left = new Node<T>(val);
}
else {
addHelper(root->left, val);
}
}
else {
if (!root->right) {
root->right = new Node<T>(val);
}
else {
addHelper(root->right, val);
}
}
}
void printHelper(Node<T> *root) {
if (!root) return;
printHelper(root->left);
cout << root->value << ' ';
cout << root->age << ' '; // ADDED
cout << root->name << ' '; //ADDED
printHelper(root->right);
}
int nodesCountHelper(Node<T> *root) {
if (!root) return 0;
else return 1 + nodesCountHelper(root->left) + nodesCountHelper(root->right);
}
int heightHelper(Node<T> *root) {
if (!root) return 0;
else return 1 + max(heightHelper(root->left), heightHelper(root->right));
}
void printMaxPathHelper(Node<T> *root) {
if (!root) return;
cout << root->value << ' ';
if (heightHelper(root->left) > heightHelper(root->right)) {
printMaxPathHelper(root->left);
}
else {
printMaxPathHelper(root->right);
}
}
bool deleteValueHelper(Node<T>* parent, Node<T>* current, T value) {
if (!current) return false;
if (current->value == value) {
if (current->left == NULL || current->right == NULL) {
Node<T>* temp = current->left;
if (current->right) temp = current->right;
if (parent) {
if (parent->left == current) {
parent->left = temp;
}
else {
parent->right = temp;
}
}
else {
this->root = temp;
}
}
else {
Node<T>* validSubs = current->right;
while (validSubs->left) {
validSubs = validSubs->left;
}
T temp = current->value;
current->value = validSubs->value;
validSubs->value = temp;
return deleteValueHelper(current, current->right, temp);
}
delete current;
return true;
}
return deleteValueHelper(current, current->left, value) ||
deleteValueHelper(current, current->right, value);
}
public:
void insert(T val) {
if (root) {
this->addHelper(root, val);
}
else {
root = new Node<T>(val);
}
}
void print() {
printHelper(this->root);
}
int nodesCount() {
return nodesCountHelper(root);
}
int height() {
return heightHelper(this->root);
}
void printMaxPath() {
printMaxPathHelper(this->root);
}
bool Delete(T value) {
return this->deleteValueHelper(NULL, this->root, value);
}
};
#endif
I created the struct using these 3 values, and a pointer to a right and left node, however, all my other functions don't seem to work with the age and name values, only the ID. This is most problamatic in my add and print function.
I'm relatively new to C++, so any help would be appreciated.
EDIT: I'm assuming my problem lies around here somewhere. The code runs just fine, but it doesn't add the age and name to the string, and I can't properly print these values, just the ID
Node<T> *root;
void addHelper(Node<T> *root, T val) {
if (root->value > val) {
if (!root->left) {
root->left = new Node<T>(val);
}
else {
addHelper(root->left, val);**
}
}
else {
if (!root->right) {
root->right = new Node<T>(val);
}
else {
addHelper(root->right, val);
}
}
}
and here
void printHelper(Node<T> *root) {
if (!root) return;
printHelper(root->left);
cout << root->value << ' ';
cout << root->age << ' '; // ADDED
cout << root->name << ' '; //ADDED
printHelper(root->right);
}
Thanks in advance!

root->left = new Node(val);
root->right = new Node(val);
It seems that you create a new node and only give it a "val", no age, no name etc, so it only has the value.
edit: I never used "Template" before, so it took me a while to figure it out. Anyways...
Solution:
When you insert a node, you need to copy all the information, not just the "value", otherwise you'll only get the "value".
void addHelper(Node<T> *root, Node<T>* n) {
if (root->value > n->value) {
if (!root->left) {
root->left = new Node<T>(n->value,n->age,n->name,NULL,NULL);
}
else {
addHelper(root->left, n);
}
}
else {
if (!root->right) {
root->right = new Node<T>(n->value,n->age,n->name,NULL,NULL);
}
else {
addHelper(root->right, n);
}
}
}
Also in "insert":
void insert(Node<T>* n) {
if (root) {
this->addHelper(root, n);
}
else {
root = new Node<T>(n->value,n->age,n->name,NULL,NULL);
}
}
Several other things you may try and see the difference:
I would initialize *root to be NULL, otherwise it may be some random stuff, and sometime I got seg fault because of that.
class BST {
private:
Node<T> *root=NULL;
If the node you're about to insert has the same "value" with an already existing node, what do you do? Your program will just add it to the right. I don't know if that's what you want, but that's what it will do.
I tested with this and it worked. Hope it will work for you, too.
int main(){
BST<int> tree;
Node<int> node1(1,10,"test1",NULL,NULL);
Node<int> node2(5,50,"test2",NULL,NULL);
Node<int> node3(3,30,"test3",NULL,NULL);
Node<int> node4(3,30,"test4",NULL,NULL);
Node<int> node5(3,30,"test5",NULL,NULL);
Node<int> node6(8,80,"test5",NULL,NULL);
tree.insert(&node1);
tree.insert(&node2);
tree.insert(&node3);
tree.insert(&node4);
tree.insert(&node5);
tree.insert(&node6);
tree.print();
cout<<endl;
return 0;
}
output:
1 10 test1 3 30 test3 3 30 test4 3 30 test5 5 50 test2 8 80 test5

Related

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!
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';
}

How to implement complete binary in c++?

I want to try make insertion of complete binary tree using recursion . I make a piece of code and I cannot catch problem why value not inserted. I make height function and count nodes function with help of these function and recursive call I want to insert new node in Complete binary tree. In main get root by using get root function then send to insert function
#include<iostream>
#include<math.h>
using namespace std;
struct node{
int data;
node *left,*right;
};
class cbt{
node *root;
public:
cbt()
{
root=NULL;
}
node* get_node()
{
return root;
}
node* newNode(int key)
{
node* temp1 = new node;
temp1->data = key;
temp1->left = temp1->right = NULL;
return temp1;
}
void CBT_inseration(node* temp,int data)
{
node *ptr;
ptr=newNode(data);
if(root==NULL)
{
root=ptr;
return;
}
else
{
height = f_height(temp->left);
int excepted_node = pow(2,height)-1;
int left_tree_node_count = countNumNodes(temp->left);
int right_tree_node_count = countNumNodes(temp->right);
if(left_tree_node_count==right_tree_node_count)
{
CBT_inseration(temp->left,data);
}
else if(excepted_node != left_tree_node_count)
{
if(temp->left == NULL)
{
temp->left = ptr;
return;
}else
{
CBT_inseration(temp->left,data);
}
}
else if(temp->right == NULL)
{
temp->right=ptr;
return;
}
else if(excepted_node != left_tree_node_count)
{
if(temp->left == NULL)
{
temp->left=ptr;
return;
}
else
{
CBT_inseration(temp->right,data);
}
}
}
}
void print(node *root) {
if (root == NULL)
return;
print(root->left);
cout << root->data << " ";
print(root->right);
}
};
int main()
{
cbt obj;
node *r=NULL;
obj.CBT_inseration(obj.get_node(),4);
obj.CBT_inseration(obj.get_node(),3);
obj.CBT_inseration(obj.get_node(),5);
obj.CBT_inseration(obj.get_node(),8);
obj.print(obj.get_node());
return 0;
}
You would need to go through a debugger to see what is wrong with your code. I will tell you how I would do this:
First, you need a function to check if the tree is full. We will reuse your functions to do this:
bool isTreeFull(node* head) {
return head != NULL && countNumNodes(head) == (1 << find_height(head)) - 1;
}
Then for inserting I have to check if the number of nodes on each side are the same. This tells me that I am allowed to move one level deeper on the left side. If the number of nodes aren't the same, then I only move on to insert on the right subtree if the left subtree is full:
void CBT_inseration(int data) {
root = insert(root, data);
}
node* insert(node* head, int data) {
if (head == NULL) {
head = newNode(data);
} else {
int leftCount = countNumNodes(head->left);
int rightCount = countNumNodes(head->right);
if (leftCount == rightCount) {
head->left = insert(head->left, data);
} else {
if (isTreeFull(head->left)) {
head->right = insert(head->right, data);
} else {
head->left = insert(head->left, data);
}
}
}
return head;
}
Then you would call it like:
cbt obj;
obj.CBT_inseration(4);
obj.CBT_inseration(3);
obj.CBT_inseration(5);
obj.CBT_inseration(6);
obj.CBT_inseration(8);
obj.print(obj.get_node()); // 6 3 8 4 5

C++ Binary Tree Programming new Nodes leaving Scope issue

I am a java programmer teaching myself C++.
While writing a binary tree I found that my program did not "add" values to the tree.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
class BinaryTree {
struct Node {
public:
int val;
Node* left;
Node* right;
Node::Node(int v) {
val = v;
left = nullptr;
right = nullptr;
}
};
public:
BinaryTree() {
root = nullptr;
}
int size = 0;
int length();
bool BinaryTree::add(int v);
void printTree();
private:
void printTree(Node* n);
Node* root;
};
bool BinaryTree::add(int v) {
if (root == nullptr) {
root = new Node(v);
++size;
return true;
}
Node* ref = root;
cout << ref->val;
while (ref != nullptr) {
if (v < ref->val) {
ref = ref->left;
}
else if (v > ref->val) {
ref = ref->right;
}
else if (v == ref->val) {
return false;
}
}
Node *newNode = new Node(v);
ref = newNode;
++size;
return true;
}
void BinaryTree::printTree() {
printTree(root);
}
void BinaryTree::printTree(Node* n) {
if (n == nullptr) {
return;
}
printTree(n->left);
cout << n->val << endl;
printTree(n->right);
}
int BinaryTree::length() {
return size;
}
void main(int i) {
BinaryTree tree = BinaryTree();
tree.add(6);
tree.add(3);
tree.add(5);
tree.add(7);
tree.add(1);
tree.add(0);
tree.add(0);
tree.printTree();
cout << "binary tree sz is " << tree.length() << endl;
while (true) {};
}
I have been unable to find the problem in regards to why the tree doesn't commit new Nodes except the root.
I used "new" in the code when writing (ref = new Node) etc in the adds method because this should prevent the new Node from being destroyed once it leaves the scope.
If anyone can enlighten me on this issue I will be greatly thankful.
To add a node to the tree you have to link it to some existing node, as in
existing_node->{left or right} = new_node;
Once ref becomes nullptr, you don't have a valid existing node anymore, and it is too late to do anything. Instead, traverse the tree as long as ref->{left or right} is valid:
if (v < ref->val) {
if (ref->left) {
ref = ref->left;
} else {
ref->left = newNode;
return true;
}
}
// etc for v > ref->val

Why isn't my function returning the count? (Binary Tree)

Everything in my program works perfectly, except it is not showing the count for the field. I tried to change some codes but it does not seem to display it in the output. It seems like a easy mistake or something obviously but I have no idea why it doesn't display it. Can someone help?
#include <iostream>
using namespace std;
template<class T>
class BinaryTree
{
struct Node
{
T data;
Node* leftChild;
Node* rightChild;
Node(T dataNew)
{
data = dataNew;
leftChild= NULL;
rightChild = NULL;
}
};
private:
Node* root;
void Add(T new_Data, Node* &the_Root)
{
if (the_Root == NULL)
{
the_Root = new Node(new_Data);
return;
}
if (new_Data < the_Root->data)
Add(new_Data, the_Root->leftChild);
else
Add(new_Data, the_Root->rightChild);
}
int countTree(Node* the_Root)
{
if (the_Root == NULL)
return 0;
else {
int count = 1;
count += countTree(the_Root->leftChild);
count += countTree(the_Root->rightChild);
return count;
}
}
void PrintTree(Node* the_Root)
{
if (the_Root != NULL)
{
cout << the_Root->data <<" ";
PrintTree(the_Root->leftChild);
PrintTree(the_Root->rightChild);
}
}
public:
BinaryTree()
{
root = NULL;
}
void AddItem(T new_Data)
{
Add(new_Data, root);
}
int countTree()
{
return countTree(root);
}
void PrintTree()
{
PrintTree(root);
}
};
int main()
{
BinaryTree<int> *myBT = new BinaryTree<int>();
myBT->AddItem(6);
myBT->AddItem(5);
myBT->AddItem(4);
myBT->AddItem(18);
myBT->AddItem(6);
myBT->PrintTree();
myBT->countTree();
}
The count won't be shown simply because you didn't write any code to show the count.
Try changing myBT->countTree(); to cout << myBT->countTree();, and you will see the count printed.
You aren't actually doing anything with the result of myBT->countTree(). Try printing it:
std::cout << myBT->countTree() << std::endl;

Write a program, which converts the expression a b + c d e + * * into an expression tree using stack.

description
I don't know how to do this task.... but i just created a tree and enter value..can anyone please help me to do this task...the Stack is also of node type and we have to push value of operators like ab+ so we will push a as node then b as node and when + will come we make a tree and a and b will be its leafs node.
.Code
#include<iostream>
using namespace std;
class Node{
public:
int data;
Node *left;
Node *right;
Node()
{
data = 0;
left = NULL;
right = NULL;
}
};
class Tree
{
Node *root;
void insert(int d, Node *node)
{
if (d < node->data)
{
if (node->left == NULL)
{
Node *leaf = new Node();
leaf->data = d;
node->left = leaf;
}
else
{
insert(d, node->left);
}
}
else
{
if (node->right == NULL)
{
Node *leaf = new Node();
leaf->data = d;
node->right = leaf;
}
else
{
insert(d, node->right);
}
}
}
void inOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
inOrderDisplay(subRoot->left);
cout << subRoot->data << " ";
inOrderDisplay(subRoot->right);
}
}
void postOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
postOrderDisplay(subRoot->left);
postOrderDisplay(subRoot->right);
cout << subRoot->data << " ";
}
}
void preOrderDisplay(Node *subRoot)
{
if (subRoot != NULL)
{
cout << subRoot->data << " ";
preOrderDisplay(subRoot->left);
preOrderDisplay(subRoot->right);
}
}
void deleteSubtree(Node *subRoot)
{
if (subRoot != NULL)
{
deleteSubtree(subRoot->left);
deleteSubtree(subRoot->right);
cout << "\ndeleting: " << subRoot->data;
delete subRoot;
subRoot = NULL;
}
}
public:
Tree()
{
root = NULL;
}
~Tree()
{
deleteAll();
}
void insert(int d)
{
if (root == NULL)
{
Node *leaf = new Node();
leaf->data = d;
root = leaf;
}
else
{
insert(d, root);
}
}
void inOrderDisplay()
{
inOrderDisplay(root);
}
void postOrderDisplay()
{
postOrderDisplay(root);
}
void preOrderDisplay()
{
preOrderDisplay(root);
}
void deleteAll()
{
deleteSubtree(root);
}
};
.Main Class:
#include<iostream>
#include"task1.h"
using namespace std;
void main()
{
Tree tree;
tree.insert(10);
tree.insert(6);
tree.insert(14);
tree.insert(5);
tree.insert(8);
tree.insert(11);
tree.insert(18);
cout << endl;
system("pause");
//tree.deleteAll();
}
Based on the code you have here, you only have a void insert(int d, Node *node) function, no void insert(operator o, Node *node) function.
I think this shows that you missed an important point here. Every node in the tree can either be an integer (as you did) or an operator. In both cases, I'd call it a string. Every node that is not a leaf must be an operator, and all leafs must be integers (or strings that represents operators/integer in our case).
Then, iterating over your input, the first three item should result in something like:
+
/ \
a b
The next step would be to build more sub trees (not sure of the definition of the input you have), keep them in your stack and then construct more inner nodes of the tree.
So if the tree I showed above is called Tree(+) (for ease of use), and the initial stack was [a,b,+,c,d,e,*,*], then after one iteration you'll have [Tree(+),c,d,e,*,*] and you continue from there.