binary tree c++ insert and update? - c++

I want to make a binary tree in c++ that perform insert operation the inserted values are 4 on a node that is
name, type , order, and color
The use will enter these 4 as INSERT corn oil 3 yellow. It create a new node with name as corn and 3 child node as type ,order and color.
If again user enter same thing but change any other except name that exists like
INSERT corn oil 4 red as corn name exist this will update node
preorder and postorder traversal with remove and find any node
Here is how i am going ?
struct TreeNode {
string itemname; // The data in this node.
TreeNode *left; // Pointer to the left subtree.
TreeNode *right; // Pointer to the right subtree.
};
1- Name node will have 2 values left right where 4th will be place
2- The hierarchy of tree is like root have only names that have 2 left right node so root have many nodes with names that have only 2 further node but no more node will be added to child node of names is it really a tree

Since you are using binary tree, I am not sure you can use string as a key for TreeNode (well I have always used intigers). So what I suggest is that you have structure like this:
// I am not sure about types, but I assumed them by name
struct Element {
char* name;
int type;
int order;
char* color;
};
struct TreeNode {
int key;
Element *element;
TreeNode *left, *right;
};
Then you would somehow calculate hash of Element::name to get a numeric value, which a is key. Now you would just traverse tree from root to the left or right depending on key. You would check on each node if key you are inserting is same as one in current node and if answer is yes, then you would swap values in that node, otherwise continue traversing the tree to the left or right. If you get to the bottom it means you haven't find a node with that key, so you create a new one and attach it as a leaf.
You can look this link to generate hash. However, keep in mind that for some string you can get same hash value, so you may need to keep more than one element at the current tree node.
UPDATE
Here is the code, however you can optimize it more by using pointers. But as mentioned in comments, if you are not strictly bound to use binary tree, you should use HashTable or std::map.
std::map<std::string, struct Element*> elements
and for retrieving element:
Element *e = elements["corn"]
Binary Tree implementation:
#include <iostream>
#include <vector>
#define A 54059 /* a prime */
#define B 76963 /* another prime */
#define C 86969 /* yet another prime */
#define FIRSTH 37 /* also prime */
struct Element {
std::string name;
std::string type;
int order;
std::string color;
};
struct TreeNode {
int key;
std::vector<Element> values;
struct TreeNode *left;
struct TreeNode *right;
};
/**
* see: https://stackoverflow.com/questions/8317508/hash-function-for-a-string
*/
int calculateHash(const char *s)
{
int h = FIRSTH;
while (*s) {
h = (h * A) ^ (s[0] * B);
s++;
}
return h; // or return h % C;
}
void printElement(Element element)
{
std::cout
<< element.name
<< " "
<< element.type
<< " "
<< element.order
<< " "
<< element.color
<< std::endl;
}
void preOrder(TreeNode* node)
{
if( node == NULL )
return;
for(size_t i=0; i<node->values.size(); i++) {
printElement(node->values[i]);
}
preOrder(node->left);
preOrder(node->right);
}
void insert(TreeNode** root, Element element, int key)
{
if( *root == NULL ) {
TreeNode* node = new TreeNode();
node->key = key;
node->values.push_back(element);
*root = node;
return;
};
if( key == (*root)->key ) {
for(size_t i=0; i<(*root)->values.size(); i++) {
if( (*root)->values[i].name == element.name ) {
(*root)->values[i].type = element.type;
(*root)->values[i].order = element.order;
(*root)->values[i].color = element.color;
break;
}
}
}
else if( key < (*root)->key ) {
insert( &((*root)->left), element, key );
}
else {
insert( &((*root)->right), element, key );
}
}
int main()
{
TreeNode *node = NULL;
insert(&node, {"corn1", "oil", 3, "yellow"}, calculateHash("corn1"));
insert(&node, {"corn2", "oil", 3, "yellow"}, calculateHash("corn2"));
insert(&node, {"corn3", "oil", 3, "yellow"}, calculateHash("corn3"));
insert(&node, {"corn2", "aaa", 32, "blue"}, calculateHash("corn2"));
preOrder(node);
return 0;
}

Related

LinkedList ADT pointer block

I am implementing a number of LinkedList ADT's for my compsci class and I'm running into the same problem on every one. The code listed below is a binary tree ADT. The compiler gets lost when trying to input data into the new nodes. The code compiles without any errors, but the compiler does not return anything, I think it's stuck trying to find the pointer. I come from Java so I'm still working my way around pointers.
#include <iostream>
struct TreeNode {
//represents a single node in a binary tree of int data
int data; //immediate data
TreeNode *left; //left subtree
TreeNode *right; //right subtree
TreeNode(int in);
};
TreeNode::TreeNode(int in) {
data = in;
left = NULL;
right = NULL;
}
The compiler can't seem to find the pointer referenced in these two append functions.
void addLeft(TreeNode *root, int newData) {
TreeNode *new_node;
new_node->data = newData;
root->left = new_node;
}
void addRight(TreeNode *root, int newData) {
TreeNode *new_node;
new_node->data = newData;
root->right = new_node;
}
//counts nodes in binary tree from designated root point
int countNodes(TreeNode *root) {
if (!root) {
return 0; //empty tree
}
int count = 1;
count += countNodes(root->left); //adds left subtree nodes
count += countNodes(root->right); //adds right subtree countNodes
return count;
}
void preorderPrint(TreeNode *root) { //root first, then left, then right
if (root) {
std::cout << root->data << " ";
preorderPrint(root->left);
preorderPrint(root->right);
}
}
void postorderPrint(TreeNode *root) { //left first, then right, then root
if (root) {
postorderPrint(root->left);
postorderPrint(root->right);
std::cout << root->data << " ";
}
}
void inorderPrint(TreeNode *root) { //left first, then root, then right
if (root) {
inorderPrint(root->left);
std::cout << root->data << " ";
inorderPrint(root->right);
}
}
bool tree_contains(TreeNode *root, int item) {
if (!root) {
return false; //if the root doesn't exist, the tree doesn't exist
}
else if (root->data = item) {
return true; //item is found in the root node
}
else if (root->data > item) {
}
}
int main() {
TreeNode *root;
root->data = 5;
addLeft(root, 4);
addRight(root,9);
inorderPrint(root);
return 0;
}
Your root is not initialized. It currently has an undefined value. It should be:
TreeNode *root = new TreeNode(5);
... // Do whatever you want
// delete root and everything else.
A pointer is just a variable that holds an address of an object in memory. When you define a pointer like
int *foo;
you haven't initialized it, so its value is indeterminate. That means it doesn't hold a valid pointer value that could be used to access an object in memory. To make a pointer actually point to something, you have to assign it an address:
int bar;
inf *foo = &bar;
Now foo holds the address of bar and you can dereference foo to write to bar:
*foo = 42;
// bar is now 42
In your code
TreeNode *root;
root->data = 5;
You try to dereference (root->data is just syntactic sugar for (*root).data) a pointer root that hasn't been initialized with or assigned a valid pointer value.
Since you want to create a dynamic data structure that grows on demand, you want to allocate memory at runtime. You could do so using the new operator:
TreeNode *root = new TreeNode; // allocates an object of the type
// TreeNode
root->data = 5; // is now safe.
But since you provide a constructor for TreeNode that takes an int you can write:
TreeNode *root = new TreeNode{ 5 };
The same goes for many other locations in your code as well.
Please remember that dynamically allocated memory should be deallocated when it is no longer needed:
`delete root;`

Level order traversal of a B-tree

I am writing a symulator of a B-tree.
I read here stackoverflow that the best way is use a queue to make a level order traversal. But i have no idea how to do it.
I work on implementation in c++ from geeksforgeeks.
Perhaps someone knows how to rebuild inorder traversal(code below) to level order traversal.
Classes and constuctors :
class BTreeNode
{
int *keys; // An array of keys
int t; // Minimum degree (defines the range for number of keys)
BTreeNode **C; // An array of child pointers
int n; // Current number of keys
int j;
bool leaf; // Is true when node is leaf. Otherwise false
public:
BTreeNode(int _t, bool _leaf); // Constructor
// A utility function to insert a new key in the subtree rooted with
// this node. The assumption is, the node must be non-full when this
// function is called
void insertNonFull(int k);
// A utility function to split the child y of this node. i is index of y in
// child array C[]. The Child y must be full when this function is called
void splitChild(int i, BTreeNode *y);
// A function to traverse all nodes in a subtree rooted with this node
void traverse();
// A function to search a key in subtree rooted with this node.
BTreeNode *search(int k); // returns NULL if k is not present.
// Make BTree friend of this so that we can access private members of this
// class in BTree functions
friend class BTree;
};
// A BTree
class BTree
{
BTreeNode *root; // Pointer to root node
int t; // Minimum degree
public:
// Constructor (Initializes tree as empty)
BTree(int _t)
{ root = NULL; t = _t; }
// function to traverse the tree
void traverse()
{ if (root != NULL)
cout << "root";
root->traverse(); }
// function to search a key in this tree
BTreeNode* search(int k)
{ return (root == NULL)? NULL : root->search(k); }
// The main function that inserts a new key in this B-Tree
void insert(int k);
};
Inorder traversal :
void BTreeNode::traverse()
{
// There are n keys and n+1 children, travers through n keys
// and first n children
int i;
for (i = 0; i < n; i++)
{
// If this is not leaf, then before printing key[i],
// traverse the subtree rooted with child C[i].
if (leaf == false)
C[i]->traverse();
cout << " " << keys[i];
}
// Print the subtree rooted with last child
if (leaf == false)
C[i]->traverse();
}
Here you can see the Depth-First-Search algorithm (wiki) recursive implementation.
For level-by-level traversal you probably need the Breadth-First-Search (wiki).
To achieve this, we will perform 2 steps.
First step: write recursion-free DFS:
void BTreeNode::traverse()
{
std::stack<BTreeNode*> stack;
stack.push(this);
while (!stack.empty())
{
BTreeNode* current = stack.top();
stack.pop();
int i;
for (i = 0; i < n; i++)
{
if (leaf == false)
stack.push(current->C[i]);
cout << " " << current->keys[i];
}
if (leaf == false)
stack.push(current->C[i]);
}
}
Second step: use queue instead of stack:
void BTreeNode::traverse()
{
std::queue<BTreeNode*> queue;
queue.push(this);
while (!stack.empty())
{
BTreeNode* current = queue.front();
queue.pop();
int i;
for (i = 0; i < n; i++)
{
if (leaf == false)
stack.push(current->C[i]);
cout << " " << current->keys[i];
}
if (leaf == false)
stack.push(current->C[i]);
}
}
So, it's done!

How to create a function that returns smallest value of an unordered binary tree

This seems like it should be really easy but I've been having trouble with this for quite some time. As the title says, I'm just trying to find the node in a Binary tree (not a BST!) with the smallest value and return it. I can write a recursive void function pretty easily that can at least assign the smallest value in the function, but I'm getting stuck on how to back track to previous nodes once I reach a NULL pointer.
I have a node class that has a pointer to a left and right child, each with its own value. Here is my (failed) attempt so far:
int preOrder(Node *node, int value, int count, int sizeOfTree)
{
count++; //keeps track of whether or not we have traversed the whole tree
if(value < node->getValue())
value = node->getValue();
if(count == sizeOfTree);
return value;
if(node == NULL)
//Want to return to the previous function call
//How do I do this for a non void function?
//for a void function, you could jsut type "return;" and the function
//back tracks to your previous place in the tree
//but since I'm returning a value, How would I go about doing this?
//these 2 calls are incorrect but the idea is that I first traverse the left subtree
//followed by a traversal of the right subtree.
preOrder(node->getLeft(), value);
preOrder(node->getRight(), value);
}
If possible, I would like to try and do this without keeping track of a "count" as well to make the code cleaner.
Let me know if anymore clarification is needed.
I don't really understand why, in your original code, you need to keep track of the amount of elements traversed. Here is my solution:
int find_min(Node* node)
{
int value = node->getValue()
Node* left_node = node->getLeft();
if (left_node != NULL)
{
int left_value = find_min(left_node);
if (left_value < value)
value = left_value;
}
Node* right_node = node->getRight();
if (right_node != NULL)
{
int right_value = find_min(right_node);
if (right_value < value)
value = right_value;
}
return value;
}
Basically what you need to do is just visit every node and keep track of the smallest value you've seen. This can actually be done fairly simply:
#include <algorithm>
#include <limits>
int preOrder(Node *node)
{
if(node == NULL) return std::numeric_limits<int>::max();
// this should never affect the calculation of the minimum
// (What could possibly be bigger than INT_MAX? At worst it's equal)
int value = std::min(
node->getValue(),
preOrder(node->getLeft())
);
value = std::min(
value,
preOrder(node->getRight())
);
return value;
}
OK, so you have an unordered binary tree and you're trying to find the lowest element in it.
Since the tree is unordered, the lowest element can be at any position in the tree, so you must search the entire tree.
The characteristics of the search will be as follows:
thorough (whole tree is searched)
recursive (rather than iterative, which would be really yucky)
base case: node is NULL
base outcome: maintain current value
Lets write it then:
#include <algorithm>
using namespace std;
int searchLowest(Node * node, int value = INT_MAX)
{
if (node == NULL) // base case
return value; // base outcome
// at this point, node must not be NULL
value = min(value, preOrder(node->getRight(), value)); // thorough, always recurse
value = min(value, preOrder(node->getLeft (), value)); // and check children
value = min(value, node->getValue());
return value;
}
Edit for thoroughness, justice, and OOness:
// Node.h
#include <algorithm>
using namespace std;
template <typename T>
class Node
{
public:
Node(T item)
{
data = item;
}
T lowest()
{
T value = data;
if (right != NULL)
value = min(value, right->lowest());
if (left != NULL)
value = min(value, left->lowest());
return value;
}
Node<T> * getRight()
{
return right;
}
Node<T> * getLeft()
{
return left;
}
private:
T data;
Node<T> * right;
Node<T> * left;
};
// main.cpp
#include <iostream>
#include "Node.h"
using namespace std;
int main(int c, char * v[])
{
Node<int> * tree = sycamore(); // makes a nice big tree
cout << tree->lowest();
}
SEE JIMMY RUN

c++ pass by reference?

/*
This program demonstrates a few routines for processing binary
sort trees. It uses a binary sort tree of strings. The user
types in strings. The user's string is converted to lower case, and --
if it is not already in the tree -- it is inserted into the tree.
Then the number of nodes in the tree and a list of items in the tree
are output. The program ends when the user enters an empty string.
*/
#include <iostream>
#include <string>
using namespace std;
class TreeNode {
// An object of type TreeNode represents one node
// in a binary tree of strings.
public:
// Constructor. Make a node containing str.
TreeNode(string str) : item(str), left(NULL), right(NULL) {}
string item; // The data in this node.
TreeNode *left; // Pointer to left subtree.
TreeNode *right; // Pointer to right subtree.
};
typedef TreeNode* TreeNodePtr;
void treeInsert(TreeNodePtr& root, string newItem);
// Add the item to the binary sort tree to which the parameter
// "root" refers. Note that root is passed by reference since
// its value can change in the case where the tree is empty.
bool treeContains( TreeNodePtr root, string item );
// Return true if item is one of the items in the binary
// sort tree to which root points. Return false if not.
void treeList(TreeNodePtr node);
// Print the items in the tree in postorder, one item
// to a line. Since the tree is a sort tree, the output
// will be in increasing order.
int countNodes(TreeNodePtr node);
// Count the nodes in the binary tree to which node
// points. Return the answer.
int main() {
TreeNodePtr root;// Pointer to the root node in a binary tree. This
// tree is used in this program as a binary sort tree.
// The tree is not allowed to contain duplicate
// items. When the tree is empty, root is null.
root = NULL; // Start with an empty tree.
cout << "This programs stores strings that you enter in a binary sort\n";
cout << "tree. After each items is inserted, the contents of the tree\n";
cout << "are displayed. The number of nodes in the tree is also output.\n";
cout << " Any string you enter will be converted to lower case.\n";
cout << "Duplicate entries are ignored.\n";
while (true) {
// Get one string from the user, insert it into the tree,
// and print some information about the tree. Exit if the
// user enters an empty string. Note that all strings are
// converted to lower case.
cout << ("\n\nEnter a string to be inserted, or press return to end.\n");
string item; // The user's input.
if (cin.peek() == '\n')
break;
cin >> item;
cin.ignore(10000,'\n'); // just in case a space and other words typed
if (treeContains(root,item)) {
// Don't insert a second copy of an item that is already
// in the tree.
cout << "\nThat item is already in the tree.\n";
}
else {
treeInsert(root,item); // Add user's string to the tree.
cout << "\nThe tree contains " << countNodes(root) << " items.\n";
cout << "\nContents of tree:\n\n";
treeList(root);
}
} // end while
cout << "\n\nExiting program.\n\n";
} // end main()
void treeInsert(TreeNodePtr& root, string newItem) {
// Add the item to the binary sort tree to which the parameter
// "root" refers. Note that root is passed by reference since
// its value can change in the case where the tree is empty.
if ( root == NULL ) {
// The tree is empty. Set root to point to a new node containing
// the new item. This becomes the only node in the tree.
root = new TreeNode( newItem );
return;
}
else if ( newItem < root->item ) {
treeInsert( root->left, newItem );
}
else {
treeInsert( root->right, newItem );
}
} // end treeInsert()
bool treeContains( TreeNodePtr root, string item ) {
// Return true if item is one of the items in the binary
// sort tree to which root points. Return false if not.
if ( root == NULL ) {
// Tree is empty, so it certainly doesn't contain item.
return false;
}
else if ( item == root->item ) {
// Yes, the item has been found in the root node.
return true;
}
else if ( item < root->item ) {
// If the item occurs, it must be in the left subtree.
return treeContains( root->left, item );
}
else {
// If the item occurs, it must be in the right subtree.
return treeContains( root->right, item );
}
} // end treeContains()
void treeList(TreeNodePtr node) {
// Print the items in the tree in inorder, one item
// to a line. Since the tree is a sort tree, the output
// will be in increasing order.
if ( node != NULL ) {
treeList(node->left); // Print items in left subtree.
cout << " " << node->item << endl; // Print item in the node.
treeList(node->right); // Print items in the right subtree.
}
} // end treeList()
int countNodes(TreeNodePtr node) {
// Count the nodes in the binary tree to which node
// points. Return the answer.
if ( node == NULL ) {
// Tree is empty, so it contains no nodes.
return 0;
}
else {
// Add up the root node and the nodes in its two subtrees.
int leftCount = countNodes( node->left );
int rightCount = countNodes( node->right );
return 1 + leftCount + rightCount;
}
} // end countNodes()
One thing not understand, why this function " void treeInsert(TreeNodePtr& root, string newItem);" has "&" mark after TreeNodePtr? others not...confused!
Thank you for anyone's help!
The root pointer is passed by reference since its value can change in the case where the tree is empty.
Cheers & hth.,
All the std::strings should also be passed by const reference. This way the whole class is not placed on the stack.

c++ binarysearchtree insert

I'm working on a project where I have to make a binary search tree that stores strings and takes account of doubles. While i've already tackled the specifics, I can't for the life of me get this damn insert function to work. It seems to only store the root node, leaving it's "children" NULL even though it does actually seem to assign the left and right pointers to new nodes. However when I attempt to output it, only the main parent (root) node exists. I guess the changes do not get saved for whatever reason.
Here's the header file:
#ifndef BST_H
#define BST_H
#include <string>
#include <vector>
#include <iostream>
using namespace std;
typedef string ItemType;
class Node
{
public:
Node(); // constructor
ItemType data; // contains item
Node* left; // points to left child
Node* right;// points to right child
int dataCount; // keeps track of repeats
vector<int> lineNumber; // keeps track of line numbers
};
class Tree
{
public:
Tree(); // constructor
// ~Tree(); // destructor. not working.
bool isEmpty(); // tests for empty tree
Node* find(Node* root, ItemType item); // finds an item
void insert(Node* root, ItemType item, int lineN, Tree tree); // inserts an item
void outputTree(Node* root); // lists all items in tree
void treeStats(Tree tree); // outputs tree stats
void clearTree(); // erases the tree (restart)
Node* getRoot(); // returns the root
void setRoot(Node*& root);
// void getHeight(Tree *root); // gets height of tree
private:
Node* root; // root of tree
int nodeCount; // number of nodes
};
#endif
cpp:
#include "BST.h"
bool setRootQ = true;
/** Node constructor- creates a node, sets children
* to NULL and ups the count. */
Node::Node()
{
left = right = NULL;
dataCount = 1;
}
/** Tree constructor- creates instance of tree
* and sets parameters to NULL */
Tree::Tree()
{
root = NULL;
nodeCount = 0;
}
/** Destructor- deallocates tree/node data;
* avoids heap leaks. SOMETHING WRONG. CAUSES SEGFAULT
Tree::~Tree()
{
if(this->root->left) // if a left child is present
{
delete this->root->left; //recursive call to destructor ("~Tree(->left)")
this->root->left = NULL;
}
if(this->root->right) // if a right child is present
{
delete this->root->right; //recursive call to destructor
this->root->right = NULL;
}
} */
/** Returns true if tree is empty.
* Otherwise returns false (DUH). */
bool Tree::isEmpty()
{
return root == NULL;
}
/** Searches tree for item; returns the node if found
* #param root- tree node.
* item- data to look for. */
Node* Tree::find(Node* root, ItemType item)
{
if(root == NULL) // if empty node
{
return NULL;
}
else if(item == root->data) // if found
{
return root;
}
else if(item < root->data) // if item is less than node
{
find(root->left, item);
}
else if(item > root->data) // if item is more than node
{
find(root->right, item);
}
return NULL;
}
/** Adds a new node to the tree. If duplicate, increases count.
* #param item- data to insert.
* root- tree node/ */
void Tree::insert(Node* root, ItemType item, int lineN, Tree tree)
{
Node* temp = find(tree.getRoot(), item);
if(temp != NULL) // if item already exists
{
temp->dataCount += 1;
temp->lineNumber.push_back(lineN);
return;
}
if(root == NULL) // if there is an empty space
{
root = new Node; // insert new node
root->data = item; // w/ data value
root->lineNumber.push_back(lineN);
nodeCount++;
if(setRootQ)
{
setRoot(root);
setRootQ = false;
}
return;
}
if(item < root->data)
{
insert(root->left, item, lineN, tree);
}
if(item > root->data)
{
insert(root->right, item, lineN, tree);
}
}
/** Outputs tree to console in inorder.
* #param root- tree root. */
void Tree::outputTree(Node* root)
{
if(isEmpty()) // if empty tree
{
cout << "Error: No items in tree" << endl; // error message
}
else
{
if(root->left != NULL)
{
outputTree(root->left);
}
cout << "- " << root->data << " (" << root->dataCount << ") line#s: ";
for(unsigned int i = 0; i < root->lineNumber.size(); i++)
{
cout << root->lineNumber[i] << ", ";
}
cout << endl;
if(root->right != NULL)
{
outputTree(root->right);
}
}
}
/** Displays tree stats including number of nodes,
* tree height, and more frequent item.
* #param tree- tree instance. */
void Tree::treeStats(Tree tree)
{
cout << "Number of entries: " << nodeCount << endl;
// unfinished
}
/** Clears tree.
void Tree::clearTree()
{
this->~Tree();
} */
/** Returns the root of the tree. */
Node* Tree::getRoot()
{
return root;
}
void Tree::setRoot(Node*& rootS)
{
root = rootS;
}
I realize my destructor isn't working but I'll tackle that myself later. I've been pulling my hair out over this trying to figure out what I'm missing, but to no avail. If anyone can give me any help and point me in the direction towards a solution I would greatly appreciate it.
i think it might have something to do with
void Tree::insert(Node* root, ItemType item, int lineN, Tree tree)
and instead should be something like
void Tree::insert(Node* &root, ItemType item, int lineN, Tree tree)
but when i try i get a "no matching function" error. :/
The solution you suggest yourself (with insert() taking Node *& root) will work. You have to make a corresponding change to the .h file, AND also change getRoot() to return Node *& in both .h and .cc files.
This will work. But your code has other problems. For example, setRoot and setRootQ don't do anything useful, as far as I can tell. The fourth argument to insert() only confuses things and does nothing to detect duplicates. It should be removed. To detect a duplicate simply do if (item == root->data) just before you do if (item < root->data) in the insert() method (i.e. it'll be even more similar to find()).
Also, if anyone besides you will ever use your code, you shouldn't require passing in getRoot() to methods like find() and insert(). Instead, create private helper methods, like find_helper(Node*, Item) and insert_helper(Node*&,Item), and have the public methods call them with the root node as the first argument. E.g.:
Node *find(Item item) { return find_helper(root, item); }
This would also make the weird return type of getRoot() unnecessary, and you could change it back to returning the plain Node*, or get rid of that accessor altogether.
Seems like there is a lot of pointer comparison occurring but the pointer member variables are not being initialized. Ensure that the pointer member variables are initialized properly so that they evaluate properly in if statements.
Change from:
class Node
{
public:
Node(); // constructor
...
};
to
class Node
{
public:
Node() : left(0), right(0) {}
...
};