C++ 'this' pointer usage inside class method - c++

I'm porting a binary tree implementation from C to C++, converting it to a class in the process.
Sorry in advance for the C way of handling most things.
The attributes consists of
T data;
node<T> *left, *right;
I'm trying to make changes to the root node through
node<T>* current = this; // points to root node
node<T> newnode = node<T>(5); // just a test value
current->left = &newnode;
cout << "current->left: " << current->left << " value: " << current->left->data << endl;
cout << "this->left: " << " value: " << this->left->data << endl;
In my mind, those two prints should print exactly the same thing, since current and this both point to the same object, but the output I got is clearly different
current->left: 0x7fffffffddb0 value: 5
this->left: 0x7fffffffddb0 value: -139656192
So they point to the same left object, but that object holds different values when viewed differently, what gives?
Additoinal Info
Declaration
template <typename T>
class node {
public:
T data;
node<T> *left, *right;
void insert(T data);
int remove(T target); // returns success or not
node<T>* find(T target);
void print(int mode); // need overloading since can't use 'this' as default var
void print(int mode, node<T>* root);
private:
node<T>* node_new(T data);
void node_find(T key, node<T>*** target_node_address_handle);
void node_delete(node<T>** target_address);
};
Constructor
template <typename T>
node<T>::node(T rootdata) {
data = rootdata;
left = NULL;
right = NULL;
}
Find method shared by insert and delete
template <typename T>
void node<T>::node_find(T key, node<T>*** target_node_address_handle) {
node<T>* current = this;
while(current) {
if (typeid(key) == typeid(current->data)) {
if (key == current->data) break;
else if (key < current->data) current = current->left;
else current = current->right;
}
}
// if loop exited without breaking, will insert into empty NULL position
*target_node_address_handle = &current;
}
My insert doesn't work, but I'm not sure if that's a problem in node_find or node_insert
template <typename T>
void node<T>::insert(T data) {
node<T>** target_node_address;
node_find(data, &target_node_address);
// target_node_address should now point to one of root's decedents
if (!(*target_node_address)) // nothing at target node as expected
*target_node_address = node_new(data);
// node_new returns pointer to node
}
Edit
Copy constructor
template <typename T>
node<T>::node(const node<T>& anothernode) {
data = anothernode.data;
if(anothernode.left) *left = *anothernode.left;
else left = NULL;
if(anothernode.right) *right = *anothernode.right;
else right = NULL;
}
Destructor (both added in declaration)
template <typename T>
node<T>::~node(void) {
left = NULL;
right = NULL;
}
Interesting thing is that it compiled fine before I explicitly added these in...

Problem solved with new node and insert changed to:
template <typename T>
node<T>* node<T>::node_new(T data) {
node<T>* newnode = new node<T>(data);
return newnode;
}
template <typename T>
void node<T>::node_find(T key, node<T>*** target_node_address_handle) {
// find node matched by key, or NULL pointer in correct location
// give node pointer address back
node<T>* root = this;
node<T>** target_address = &root;
while(*target_address) {
node<T>* current = *target_address;
if(typeid(key) == typeid(current->data)) {
// assume comparison operator exists
if(key == current->data)
break;
else if(key < current->data)
target_address = &current->left;
else
target_address = &current->right;
}
}
// if loop exited without breaking, will insert into an empty NULL position
// else loop exited by matching/breaking, will delete non-NULL node
*target_node_address_handle = target_address;
}
Problem was I was giving &current back to *target_node_address_handle, which would be an address to a pointer to NULL, rather than a pointer to a pointer to NULL, which I could change.

Related

BST Node Deletion - Pointer not being deleted correctly?

I'm running some tests on a simple 3 node binary search tree. Root node has a value of 1 and its left and right children have values of 0 and 2, respectively.
Here's the source code (3 files):
File name: bst.cpp
#include <iostream>
#include "bst.h"
template <typename T>
void binary_search_tree<T>::insert(const T val2ins)
{
num_nodes++;
if(!root)
{
root = new tree_node<T>(val2ins, nullptr, nullptr, nullptr);
return;
}
//loop from root until we find where to insert val2ins; seek to find a suitable parent with a nullptr
auto curr_node = root;
tree_node<T> *prev_node = nullptr;
while(curr_node)
{
prev_node = curr_node;
if(val2ins >= curr_node->val) //assign equalities on right children
{
curr_node = curr_node->right;
}
else
{
curr_node = curr_node->left;
}
}
//prev_node is the parent of curr_node
curr_node = new tree_node<T>(val2ins, prev_node, nullptr, nullptr);
//curr_node now points to a tree_node that contains a pointer to to the previous node
//we also need to go to previous_node and set its left/right children to curr_node
if(curr_node->val < prev_node->val)
{
prev_node->left = curr_node;
}
else
{
prev_node->right = curr_node;
}
}
template <typename T>
tree_node<T> *binary_search_tree<T>::get_root()
{
return root;
}
File name: bst.h
#ifndef _BST_H_
#define _BST_H_
template<typename T>
struct tree_node
{
T val;
tree_node *parent;
tree_node *left;
tree_node *right;
tree_node() : val(0), parent(nullptr), left(nullptr), right(nullptr) {}
tree_node(T val2ins, tree_node *p_ptr, tree_node *l_ptr, tree_node *r_ptr)
{
val = val2ins;
parent = p_ptr;
left = l_ptr;
right = r_ptr;
}
};
template<typename T>
class binary_search_tree
{
private:
int num_nodes;
tree_node<T> *root;
//helper function for deletion
void transplant(const tree_node<T> *node2replace, const tree_node<T> *node2insert);
public:
binary_search_tree() : num_nodes(0), root(nullptr) {}
binary_search_tree(int N, tree_node<T> *ptr) : num_nodes(N), root(ptr) {}
void insert(const T val2ins);
void delete_node(const tree_node<T> *node2del);
tree_node<T> *get_root();
// void
};
#endif
File name: main.cpp
#include <iostream>
#include "bst.h"
#include "bst.cpp"
template <typename T>
class Solution {
public:
tree_node<T> *trimBST(tree_node<T> *root, int L, int R) {
search_and_delete(root, L, R);
return root;
}
void search_and_delete(tree_node<T> *&node, const int L, const int R)
{
if(!node)
{
return;
}
if(node && node->val >= L && node->val <= R)
{
trimBST(node->right, L, R);
std::cout << node->left << std::endl;
trimBST(node->left, L, R);
std::cout << node->left << std::endl;
std::cout << node->left << std::endl;
}
else if(node && node->val > R)
{
//delete right sub tree
//then check left sub tree
//Also need to delete current node and link left (if needed)
//this can be done by simply setting current node to its left
if(node->left == nullptr && node->right == nullptr)
{
delete node;
node = nullptr;
return;
}
if(node->right)
{
delete node->right;
node->right = nullptr;
}
if(node->left)
{
node = node->left;
}
}
else if(node && node->val < L)
{
//delete left sub tree
//then check right sub tree
//Also need to delete current node and link right (if needed)
//this can be done by simply setting current node to
//its right
if(node->left == nullptr && node->right == nullptr)
{
std::cout << "deleting node 0" << std::endl;
std::cout << "Address prior to freeing: " << node << std::endl;
delete node;
node = nullptr;
std::cout << "Address after freeing: " << node << std::endl;
return;
}
if(node->left)
{
delete node->left;
node->left = nullptr;
}
if(node->right)
{
node = node->right;
}
std::cout << "done" << std::endl;
}
std::cout << "end" << std::endl;
}
};
int main(int argc, char const *argv[])
{
/* code */
binary_search_tree<int> my_tree;
Solution<int> soln;
my_tree.insert(1);
my_tree.insert(0);
my_tree.insert(2);
soln.trimBST(my_tree.get_root(), 1, 2);
return 0;
}
When I execute this code I get the following output:
0x0
0x0
0x0
end
0x7fdeaec02af0
deleting node 0
Address prior to freeing: 0x7fdeaec02af0
Address after freeing: 0x0
0x7fdeaec02af0
0x7fdeaec02af0
end
The pointer pointing to the node with value 0 is being deleted during the recursive call and set to nullptr. However, when it returns from the recursive call (where the pointer was passed by reference), the pointer is still pointing to the same memory address as it did prior to being deleted and set to nullptr.
I cannot figure out why this is happening. My only guess is that I have a memory leak somewhere that's causing issues with the pointer that I supposedly applied delete to.
At first let me to say you that your node struct just should have one content and two pointer of himself that will show the right and left children.
then for showing the BST you should cout the data NOT this pointers
class node
{
friend class BST;
public:
node(int Content=0,node* R_child = NULL, node*L_child = NULL)
{
this->R_child = R_child;
this->L_child = L_child;
this->Content = Content;
}
private:
int Content;
node*R_child;
node*L_child;
};
check this code for node class you can use template instead of integer.
Good Luck

Memory leak, Node list C++

I have this code from an old exam, which I want fix from its faults. Everytime I call insertlast/insertfirst I allocate new memory for my list which I can't seem to free. I have run it with valgrind and gets a new leak everytime i call insertfirst/insertlast. Valgrind also complains on my loop where I try to free the memory. I get something like this:
Invalid free() / delete / delete[] / realloc()
==4548== at 0x4C2C2BC: operator delete(void*)(in/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4548== by 0x4007D6: main (code6.cpp:67)
==4548== Address 0xffefffea0 is on thread 1's stack
Here's the code:
#include <iostream>
using namespace std;
template <class T>
struct Node {
Node() : data(T()), next(nullptr) {}
Node(T d, Node * p) : data(d), next(p) {}
T data;
Node<T> * next;
};
template <class T>
void insertlast (Node<T> * p, T data) {
if (p == nullptr) {
p = new Node<T>(data, nullptr);
} else {
while (p -> next != nullptr) {
p = p -> next;
}
p -> next = new Node<T>(data, nullptr);
}
}
template <class T>
void insertfirst (Node<T> * & p, const T & data) {
Node<T> * tmp = new Node<T>(data, p);
p = tmp;
}
template <class T>
void printNode(Node<T> *& node) {
cout << node->data << " -> ";
while (node->next != nullptr) {
node = node->next;
cout << node->data << " -> ";
}
cout << endl;
}
template <class T>
void printNode2(Node<T> & node) {
cout << node.data << " -> ";
while (node.next != nullptr) {
node = *node.next;
cout << node.data << " -> ";
}
cout << endl;
}
int main() {
Node<int> node;
Node<int> * temp = &node;
Node<int> * ref = &node;
insertlast(ref, 5);
insertfirst(ref, 3);
insertlast(ref, 6);
insertfirst(ref, 2);
//printNode(ref);
//printNode2(node);
while(ref->next != nullptr){
temp = ref->next;
delete ref;
ref = temp;
}
return 0;
}
It would be cool if you could help me out to find out what's wrong with the code. My guess is that it's something fishy with the pointer reference in insertfirst, but I can't figure it out.
Thanks in advance!
When you call insertfirst the first time, you will create a new node whose next pointer is the statically allocated node object from main, then when you loop over the list to delete the nodes in it, you will try to delete this node object.
What you should do, if you want a sentinel object at the head of the list, is to make its next pointer point to the new node, and the new node should have its next pointer set to p->next. So something like
template <class T>
void insertfirst (Node<T> * head, const T & data) {
Node<T> * tmp = new Node<T>(data, head->next);
head->next = tmp;
}
Finally a hint on how to debug these things: Draw it on paper! After every operation, draw it out on paper, and problems like this would have been very easy to spot.
In your insertlast function, if the argument p is NULL, then your code will leak an instance of Node. You create the new instance and assign its address to p, but once you leave the function, p goes out of scope and you no longer have a pointer to the newly created instance.
I suppose you wanted to pass a reference to p like in your insertfirst function, but forgot to put the & char in there.
There is inconsistent interface of these two functions
template <class T>
void insertlast (Node<T> * p, T data) {
if (p == nullptr) {
p = new Node<T>(data, nullptr);
} else {
while (p -> next != nullptr) {
p = p -> next;
}
p -> next = new Node<T>(data, nullptr);
}
}
template <class T>
void insertfirst (Node<T> * & p, const T & data) {
Node<T> * tmp = new Node<T>(data, p);
p = tmp;
}
In the first function parameters are declared like Node<T> * p, T data while in the second function they are declared like Node<T> * & p, const T & data
In the first function you also shall pass the first parameter by reference. Otherwise p is a local variable of the function and changes of it will not influence to the original argument.
In can be defined the following way
template <class T>
void insertlast ( Node<T> * &p, const T &data )
{
if ( p == nullptr )
{
p = new Node<T>(data, nullptr);
}
else
{
Node<T> *tmp = p;
while ( tmp->next != nullptr )
{
tmp = tmp->next;
}
tmp->next = new Node<T>( data, nullptr );
}
}
Also you have to initialize the first node in main to nullptr
Node<int> *node = nullptr;
It is a bad idea to define the first node of the list in the stack. It is simply an invalid design.

C++: Expected Constructor, Destructor or Type Conversion

Trying to learn C++. Was wondering if someone could point me in the right direction on this error (pun intended).
The class is a LinkedList (reproduced in its entirety below). The error occurs on this line:
LinkedList<T>::ListNode LinkedList::find(int pos) const {
and says:
expected constructor, destructor, or type conversion before
'LinkedList'
Any tips would be greatly appreciated.
#ifndef LINKEDLIST_HPP
#define LINKEDLIST_HPP
#include <iostream>
using namespace std;
template <class T>
class LinkedList {
private:
// a ListNode consists of the item and a pointer to the next ListNode
struct ListNode {
T data;
ListNode *next;
};
int size; //Size of the list
ListNode *head; //the beginning of the list
public:
LinkedList(); // default oonstructor
~LinkedList(); // destructor
virtual bool isEmpty ();
virtual int getLength ();
virtual void insert (int pos, T item);
virtual T remove (int pos);
virtual T retrieve (int pos);
//helper methods
LinkedList(LinkedList &copyList); //copy constructor
ListNode *find (int pos) const; // internal find function
};
//default constructor
template <class T>
LinkedList<T>::LinkedList() {
size = 0;
head = NULL;
}
//destructor
template <class T>
LinkedList<T>::~LinkedList() {
//loop through each node, and delete it
ListNode* current = head;
while (current != NULL) {
ListNode* next = current->next;
delete current;
current = next;
}
head = NULL; // set head node to back to null
}
//copy constructor
template <class T>
LinkedList<T>::LinkedList(LinkedList& copyList) {
size = copyList.size;
// if copyList is empty
if (copyList.head == NULL)
head = NULL;
else {
//create a new head
head = new ListNode;
head->data = copyList.head->data;
//create a new list
ListNode *newPtr = head; // start at the head
// iterate through rest of list to be copied
for (ListNode *copyPtr = copyList.head->next; copyPtr != NULL; copyPtr = copyPtr->next) {
newPtr->next = new ListNode;
newPtr->data = copyPtr->data;
}
//make last ListNode's next point to NULL
newPtr->next = NULL;
}
}
template <class T>
bool LinkedList<T>::isEmpty() {
if (size == 0)
return true;
return false;
}
template <class T>
int LinkedList<T>::getLength() {
return size;
}
// used in other methods to find a given index
template <class T>
LinkedList<T>::ListNode LinkedList::find(int pos) const {
// check that pos is in bound of LinkedList
if ((pos < 1) || pos > getLength()) {
cout << "Find position of out bounds" << endl;
return NULL;
} else { //search through ListNodes
ListNode *temp = head; // start at the head
for (int i = 1; i < pos; ++i)
temp = temp->next;
return temp;
}
}
template <class T>
T LinkedList<T>::retrieve(int pos) {
T tempData; // to hold retrieved data
try {
if ((pos < 1) || (pos > getLength())) {
cout << "Retrieve request outside LinkedList's bounds" << endl;
return NULL;
}
else { //traverse list
ListNode *temp = find(pos);
tempData = temp->data;
return tempData;
}
} catch (int e) {
cout << "Could not retrieve position " << pos << endl;
}
}
template <class T>
void LinkedList<T>::insert(int pos, T item) {
//check bounds
if ((pos < 1) || (pos > getLength() +1))
cout << "Must insert at a position between 1 and getLength() + 1" << endl;
else {
try {
//create new ListNode
ListNode *temp = new ListNode;
temp->data = item;
//if the new item is at the first position
if (pos == 1) {
temp->next = head;
head = temp;
}
else {
ListNode *prev = find(pos - 1);
temp->next = prev->next;
prev->next = temp;
}
//increment size
++size;
} catch (int e) {
cout << "Error inserting " << item << " at position " << pos << endl;
}
}
}
template <class T>
T LinkedList<T>::remove(int pos) {
//check bounds
if ((pos < 1) || (pos > getLength()))
cout << "Must remove a position between 1 and getLength()" << endl;
else {
try {
ListNode *temp; //to hold shifted node
//if node to be deleted is first node
if (pos == 1) {
temp = head;
head = head->next;
}
//for anything but the head
//write over the node before the pos'th index
else {
ListNode *prev = find(pos - 1);
temp = prev->next;
prev->next = temp->next;
}
//destroy temp, to free up memory
temp->next = NULL;
delete temp;
//decrement size
--size;
} catch (int e) {
cout << "Error removing item from position " << pos << endl;
}
}
}
#endif /* LINKEDLIST_HPP */
ListNode is a dependant type, so it needs to be qualified with typename. Also, your find function was declared to return a pointer-to-ListNode, but the definition returns a ListNode by value. This seems like a simple typo:
template <class T>
typename LinkedList<T>::ListNode* LinkedList<T>::find(int pos) const {
Qualify the dependant type with typename and add <T> (I'm not sure if this is necessary, might as well do it though):
typename LinkedList<T>::ListNode* LinkedList<T>::find(int pos) const {
See: Where and why do I have to put the "template" and "typename" keywords?
Also, your definition doesn't match. In-class it returns a pointer, but outside it returns a value.
Should be
LinkedList<T>::ListNode LinkedList<T>::find(int pos) const {

C++ Templated Class Invalid Use of Incomplete Class

Trying to learn C++. I'm getting an error in my code, in the line:
class LinkedList : public LinkedList<T> {
The error says:
invalid use of incomplete type 'class
LinkedList,
std::allocator > >' declaration of 'class
LinkedList,
std::allocator > >'
Can anyone point out what I'm doing wrong? Here is the entire code.
#ifndef LINKEDLIST_HPP
#define LINKEDLIST_HPP
#include <iostream>
using namespace std;
template <class T>
class LinkedList : public LinkedList<T> {
private:
// a ListNode consists of the item and a pointer to the next ListNode
struct ListNode {
T data;
ListNode *next;
};
int size; //Size of the list
ListNode *head; //the beginning of the list
public:
LinkedList(); // default oonstructor
~LinkedList(); // destructor
virtual bool isEmpty ();
virtual int getLength ();
virtual void insert (int pos, T item);
virtual T remove (int pos);
virtual T retrieve (int pos);
//helper methods
LinkedList(LinkedList &copyList); //copy constructor
ListNode *find (int pos) const; // internal find function
};
//default constructor
template <class T>
LinkedList<T>::LinkedList() {
size = 0;
head = NULL;
}
//destructor
template <class T>
LinkedList<T>::~LinkedList() {
//loop through each node, and delete it
ListNode* current = head;
while (current != NULL) {
ListNode* next = current->next;
delete current;
current = next;
}
head = NULL; // set head node to back to null
}
//copy constructor
template <class T>
LinkedList<T>::LinkedList(LinkedList& copyList) {
size = copyList.size;
// if copyList is empty
if (copyList.head == NULL)
head = NULL;
else {
//create a new head
head = new ListNode;
head->data = copyList.head->data;
//create a new list
ListNode *newPtr = head; // start at the head
// iterate through rest of list to be copied
for (ListNode *copyPtr = copyList.head->next; copyPtr != NULL; copyPtr = copyPtr->next) {
newPtr->next = new ListNode;
newPtr->data = copyPtr->data;
}
//make last ListNode's next point to NULL
newPtr->next = NULL;
}
}
template <class T>
bool LinkedList<T>::isEmpty() {
if (size == 0)
return true;
return false;
}
template <class T>
int LinkedList<T>::getLength() {
return size;
}
// used in other methods to find a given index
template <class T>
LinkedList<T>::ListNode LinkedList<T>::find(int pos) const {
// check that pos is in bound of LinkedList
if ((pos < 1) || pos > getLength()) {
cout << "Find position of out bounds" << endl;
return NULL;
} else { //search through ListNodes
ListNode *temp = head; // start at the head
for (int i = 1; i < pos; ++i)
temp = temp->next;
return temp;
}
}
template <class T>
T LinkedList<T>::retrieve(int pos) {
T tempData; // to hold retrieved data
try {
if ((pos < 1) || (pos > getLength())) {
cout << "Retrieve request outside LinkedList's bounds" << endl;
return NULL;
}
else { //traverse list
ListNode *temp = find(pos);
tempData = temp->data;
return tempData;
}
} catch (int e) {
cout << "Could not retrieve position " << pos << endl;
}
}
template <class T>
void LinkedList<T>::insert(int pos, T item) {
//check bounds
if ((pos < 1) || (pos > getLength() +1))
cout << "Must insert at a position between 1 and getLength() + 1" << endl;
else {
try {
//create new ListNode
ListNode *temp = new ListNode;
temp->data = item;
//if the new item is at the first position
if (pos == 1) {
temp->next = head;
head = temp;
}
else {
ListNode *prev = find(pos - 1);
temp->next = prev->next;
prev->next = temp;
}
//increment size
++size;
} catch (int e) {
cout << "Error inserting " << item << " at position " << pos << endl;
}
}
}
template <class T>
T LinkedList<T>::remove(int pos) {
//check bounds
if ((pos < 1) || (pos > getLength()))
cout << "Must remove a position between 1 and getLength()" << endl;
else {
try {
ListNode *temp; //to hold shifted node
//if node to be deleted is first node
if (pos == 1) {
temp = head;
head = head->next;
}
//for anything but the head
//write over the node before the pos'th index
else {
ListNode *prev = find(pos - 1);
temp = prev->next;
prev->next = temp->next;
}
//destroy temp, to free up memory
temp->next = NULL;
delete temp;
//decrement size
--size;
} catch (int e) {
cout << "Error removing item from position " << pos << endl;
}
}
}
#endif /* LINKEDLIST_HPP */
template <class T>
class LinkedList : public LinkedList<T> {
This doesn't make sense. It is like this:
class A : public A
Does this make sense to you? How exactly?
The class you're deriving from doesn't exist, rather it is being defined while you're deriving from it, so the compiler doesn't know what the base supposed to be. The compiler need to know the full definition of the base class before you derive from it.
Nawaz gave the right answer.
Just to give a few off-topic informations :
make your destructor virtual (even if inheriting from a templated container is not something very c++-ish).
Use const where it belongs :
LinkedList(const LinkedList &copyList); //copy constructor
virtual bool isEmpty () const;
// etc.
Obviously, in real life you would use an stl container like std::list ;)

C++ Binary Search Tree Insert via Recursion

So my code is below. I'm not getting any errors and it places everything in the node just fine. But based on my debug statements Everytime anything is inserted it's finding the root. I'm not sure if that is right. But according to output file for the assignment, my answers are different when it comes to the height of the tree, the traversals, and I just flat am still having troubles with my leaf count function. Another story though.
Based on the debug statements it looks like everything is going right where they should. But I figure I might need fresh eyes. I don't see how my traversals could change at all since it is really only a matter of where I'm proccessing the node that should effect the Inorder, preorder, and postorder.
template <class T>
void BT<T>::insert(const T& item)
{
Node<T>* newNode;
newNode = new Node<T>(item);
insert(root, newNode);
}
template <class T>
void BT<T>::insert(struct Node<T> *&root, struct Node<T> *newNode)
{
if (root == NULL)
{
cout << "Root Found" << newNode->data << endl;
root = newNode;
}
else
{
if (newNode->data < root->data)
{
insert(root->left, newNode);
cout << "Inserting Left" << newNode-> data << endl;
}
else
{
insert(root->right, newNode);
cout << "Inserting Right" << newNode->data << endl;
}
}
}
My height function is as follows just in case my insert is actually fine.
template <class T>
int BT<T>::height() const
{
return height(root);
}
template <class T>
int BT<T>::height(Node<T>* root) const
{
if (root == NULL)
return 0;
else
{
if (height(root->right) > height(root->left))
return 1 + height(root-> right);
return 1 + height(root->left);
}
}
You need to change the wording of your debug statements
Really it should read (not Root node)
cout << "Leaf Node Found" << newNode->data << endl;
It is only the root when it is first called after that any call with node->left or node->right makes it an intermediate node.
To write height() I would do this:
template <class T>
int BT<T>::height(Node<T>* root) const
{
if (root == NULL) {return 0;}
return 1 + max(height(root->left),height(root->right));
}
You need to start off with your root init'd to null. Also, you are passing *&node in; it should be *node. Else you're passing a pointer to the address(or reference, I'm not sure which in this context, but both aren't going to be right). You should be passing a pointer to Node in, not a reference.
template <class T>
void BT<T>::BT()
{ root = 0;}
template <class T>
void BT<T>::insert(const T& item)
{
Node<T>* newNode;
newNode = new Node<T>(item);
insert(root, newNode);
}
template <class T>
void BT<T>::insert(struct Node<T> *root, struct Node<T> *newNode)
{
/*stuff*/
}
#Vlion:
It should be a pointer to the left/right/root pointers (i.e. a double pointer), so the posted code is correct, although somewhat unclear.
#Doug:
Consider changing your insert function thus:
template <class T>
void BT<T>::insert(struct Node<T>** root, struct Node<T>* newNode)
{
if (*root == NULL)
{
cout << "Root Found" << newNode->data << endl;
*root = newNode;
}
It makes clear your intention that you'll be changing the pointer passed as the first parameter (or rather, the pointer whose address will be passed as the first parameter.) It will help avoid confusion such as the one that just happened.
The calls to this insert(), such as:
insert(&root, newNode);
will also reflect your intention of changing the pointer's value. This is a matter of style, though, so I can't argue if you don't want to change.
As for checking whether the tree is "correct," why not draw it out and see for yourself? Something along the lines of:
template class<T>
void printTree(struct Node<T>* node, int level=0)
{
if (!node) {
for (int i=0; i<level; ++i)
cout << " ";
cout << "NULL" << endl;
return;
}
printTree(node->left, level+1);
for (int i=0; i<level; ++i)
cout << " ";
cout << node->data << endl;
printTree(node->right, level+1);
}
(Untested code)