Something wrong when deleting an element in a Binary search tree - c++

I only use function insert, remove and midorder.
#include<iostream>
template<class Elem>
class BinNode
{
public:
virtual Elem& getVal() = 0;
};
template<class Elem>
class BinNodePtr:public BinNode<Elem>
{
public:
Elem val;
BinNodePtr* lc;
BinNodePtr* rc;
BinNodePtr()
{
lc = rc = NULL;
}
~BinNodePtr()
{
delete lc;
delete rc;
}
Elem& getVal()
{
return this->val;
}
};
template<class Elem>
class BST
{
public:
BinNodePtr<Elem> *root;
int nodenum;
void midorder(BinNodePtr<Elem>* start);
public:
BST()
{
root = NULL;
nodenum = 0;
}
bool insert(BinNodePtr<Elem>*&ptr,const Elem &e);//
void remove(BinNodePtr<Elem>*&start,const Elem &e);//
BinNodePtr<Elem>* getRoot(){return root;}
};
template<class Elem>
void BST<Elem>::midorder(BinNodePtr<Elem> *start)
{
if(start == NULL) return;
midorder(start->lc);
printf("%d ",start->getVal());
midorder(start->rc);
}
template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>*&ptr,const Elem &e)
{
if(ptr == NULL)
{
ptr = new BinNodePtr<Elem>;
ptr->lc = NULL;
ptr->rc = NULL;
ptr->val = e;
return true;
}
else
{
if(ptr->val < e || ptr->val == e)
{
insert(ptr->rc,e);
}
else
{
insert(ptr->lc,e);
}
}
return false;
}
template<class Elem>
void BST<Elem>::remove(BinNodePtr<Elem>*&start,const Elem &e)
{
if(start == NULL)
return ;
if(start->val < e)
remove(start->rc,e);
else if(start->val > e)
remove(start->lc,e);
else
{
if(start->lc == NULL && start->rc == NULL)
{
delete start;
}
else if(start->lc == NULL)
{
BinNodePtr<Elem> *temp = start;
start = start->rc;
delete (temp);
}
else if(start->rc == NULL)
{
BinNodePtr<Elem> *temp = start;
start = start->lc;
delete temp;
}
else
{
BinNodePtr<Elem>* temp = start->rc;
while(temp->lc!= NULL)
{
temp = temp->lc;
}
start->val = temp->val;
remove(start->rc,temp->val);
}
}
}
int main()
{
BST<int> myBST;
(myBST.insert(myBST.root,10));
(myBST.insert(myBST.root,20));
(myBST.insert(myBST.root,5));
(myBST.insert(myBST.root,30));
myBST.midorder(myBST.getRoot());
myBST.remove(myBST.root,10);
myBST.midorder(myBST.getRoot());
system("pause");
return 0;
}
I have successfully inserted 10, 20, 5, 30 because I can "printf" them out, but the program breaks down when I use function remove. I debugged this and found that there is something wrong in function remove but I don't know how to fix it.

Related

Encountering Error Trying to use a Void Function in a FuncType Parameter

First off code:
`int main(int argc, char** argv)
{
fstream inFile;
inFile.open(argv[1]);
//where 'filename' is a string variable containing the filename
if (inFile.fail())
{
cerr<<"Error opening "<<argv[1]<<endl;
exit(1); //terminate the program
}
else{
string word;
AVLTree<WordStat> avl;
BSTree<WordStat> binary;
while(inFile >> word) {
WordStat a(word, 0);
avl.insert(a);
binary.insert(a);
}
cout << "Table 1:Binary Search Tree [" << argv[1] << "]" << endl;
cout << "In-order Traversal" << endl;
cout << "===================================" << endl;
cout << "Word Frequency" << endl;
cout << "----------------------------------" << endl;
while (binary.isEmpty() != true){
binary.traverse(printResults);
}`
Binary tree implementation:
template <typename E>
BSTree<E>::Node::Node(E s)
{
data = s;
left = NULL;
right = NULL;
}
/* Outer BSTree class definitions */
template <typename E>
BSTree<E>::BSTree()
{
root = NULL;
count = 0;
}
template <typename E>
BSTree<E>::~BSTree()
{
recDestroy(root);
}
template <typename E>
bool BSTree<E>::isEmpty() const
{
return root == NULL;
}
template<typename E>
void BSTree<E>::insert(E item)
{
Node* tmp;
Node* newnode = new Node(item);
/* If it is the first node in the tree */
if (isEmpty())
{
root = newnode;
count++;
return;
}
/*find where it should go */
tmp = root;
while (1)
{
if (tmp->data == item)
{ /* Key already exists. */
tmp->data = item;
delete newnode; /* don’t need it */
return;
}
else if (tmp->data > item)
{
if (!(tmp->left))
{
/* If the key is less than tmp */
tmp->left = newnode;
count++;
return;
}
else
{
/* continue searching for insertion pt. */
tmp = tmp->left;
}
}
else
{
if (!(tmp->right))
{
/* If the key is greater than tmp */
tmp->right = newnode;
count++;
return;
}
else
/* continue searching for insertion point*/
tmp = tmp->right;
}
}
}
template<typename E>
bool BSTree<E>::inTree(E item) const
{
Node* tmp;
if (isEmpty())
return false;
/*find where it is */
tmp = root;
while (1)
{
if (tmp->data == item)
return true;
if (tmp->data > item)
{
if (!(tmp->left))
return false;
/* continue searching */
tmp = tmp->left;
}
else
{
if (!(tmp->right))
return false;
/* continue searching for insertion pt. */
tmp = tmp->right;
}
}
}
template<typename E>
void BSTree<E>::remove(const E& item)
{
Node* nodeptr;
nodeptr = search(item);
if (nodeptr)
{
remove(nodeptr);
count--;
}
}
template<typename E>
const E& BSTree<E>::retrieve(const E& key) const throw (BSTreeException)
{
Node* tmp;
if (isEmpty())
throw BSTreeException("Binary Search Tree Exception: tree empty on retrieve()");
tmp = root;
while(tmp)
{
if (tmp->data == key)
return tmp->data;
if (tmp->data > key)
tmp = tmp->left;
else
tmp = tmp->right;
}
if (tmp == NULL)
throw BSTreeException("Binary Search Tree Exception: key does not exist on retrieve()");
return tmp->data;
}
template<typename E>
void BSTree<E>::traverse(FuncType func)
{
traverse(root,func);
}
template<typename E>
int BSTree<E>::size() const
{
return count;
}
template<typename E>
int BSTree<E>::height() const
{
return height(root);
}
template<typename E>
int BSTree<E>::depth(const E& item) const
{
Node* tmp;
tmp = root;
int depth;
while(tmp != NULL)
{
if (tmp->data == item)
return tmp->data;
if (tmp->data > item)
{
if (tmp->left == NULL)
break;
tmp = tmp->left;
depth++;
}
else
{
if (tmp->right == NULL)
break;
tmp = tmp->right;
depth++;
}
}
return depth;
}
template<typename E>
void BSTree<E>::recDestroy(Node* root)
{
if (root)
{
if (root->left) recDestroy(root->left);
if (root->right) recDestroy(root->right);
delete root;
}
}
template<typename E>
typename BSTree<E>::Node* BSTree<E>::findParent(Node* node)
{
Node* tmp;
tmp = root;
if (tmp == node)
return NULL;
while(1)
{
assert(tmp->data != node->data);
if (tmp->data > node->data)
{
assert(tmp->left != NULL);
if (tmp->left == node)
return tmp;
tmp = tmp->left;
}
else
{
assert(tmp->right != NULL);
if (tmp->right == node)
return tmp;
tmp = tmp->right;
}
}
}
template<typename E>
void BSTree<E>::traverse(Node* node, FuncType func)
{
if (node)
{
traverse(node->left,func);
func(node->data);
traverse(node->right,func);
}
}
template<typename E>
typename BSTree<E>::Node* BSTree<E>::search(const E& item)
{
Node* tmp;
tmp = root;
while(tmp)
{
if (tmp->data == item)
return tmp;
if (tmp->data > item)
tmp = tmp->left;
else
tmp = tmp->right;
}
return tmp;
}
template<typename E>
bool BSTree<E>::remove(Node* node)
{
E data;
Node* parent;
Node* replacement;
parent = findParent(node);
if (node->left && node->right)
{
replacement = node->right;
while (replacement->left)
replacement = replacement->left;
data = replacement->data;
remove(replacement);
node->data = data;
return true;
}
else
{
if (node->left)
replacement = node->left;
else if (node->right)
replacement = node->right;
else
replacement = NULL;
if (!parent)
root = replacement;
else if (parent->left == node)
parent->left = replacement;
else
parent->right = replacement;
delete node;
return true;
}
}
template<typename E>
int BSTree<E>::height(Node* node) const
{
int h = 0;
if (node != NULL)
{
int l_height = height(node->left);
int r_height = height(node->right);
int max_height = max(l_height, r_height);
h = max_height + 1;
}
return h;
}
template<typename E>
void BSTree<E>::levelTraverse(FuncType func)
{
queue<E> q;
q.push(root);
while (q.empty() != true){
Node *tmp = q.pop();
func(tmp);
q.push(tmp->left);
q.push(tmp->right);
}
}
When running the main above, it causes an error with the transverse function in the binary tree as follows "main.cpp:67:36: error: invalid conversion from 'void ()(WordStat)' to 'BSTree::FuncType {aka void ()(const WordStat&)}' [-fpermissive]
binary.traverse(printResults);"
Was wondering if anyone had any leads on fixing this. Thanks!
I think changing printResults interface to void printResults(const WordStat&) will solve the problem

Infix to Postfix code conversion

I have problem to convert infix to postfix this is my code it takes the characterinfix input but does not show any postfix output Please tell me whats the problem.I have been trying to solve it but i found no problem in it i will be thanks full you if someone find the problem.And the other thing is how may i add {} and [] this brackets too ?
#include <iostream>
#include<string.h>
using namespace std;
template <class T>
class Node
{
public:
T info;
Node *ptrnext;
Node *ptrprevious;
Node()
{
info = 0;
ptrnext = 0;
ptrprevious = 0;
}
Node(T e, Node *n, Node *p)
{
info = e;
ptrnext = n;
ptrprevious = p;
}
};
template <class T>
class DLinkedList
{
private:
Node<T> *head;
Node<T> *tail;
public:
DLinkedList()
{
head = 0;
tail = 0;
}
bool isEmpty();
void addToHead(T e);
void addToTail(T e);
void deleteFromHead();
void deleteFromTail();
void display();
T getHead();
int numofNodes();
~DLinkedList(){
if(!isEmpty())
{
while(head!=0){
if(head==tail)
{
delete head;
head=0;
tail=0;
}
else{
Node<T> *ptrtemp=head;
head=head->ptrnext;
head->ptrprevious=NULL;
delete ptrtemp;
}
}
}
}
};
template <class T>
bool DLinkedList<T>::isEmpty()
{
if (head == 0)
{
return true;
}
else
{
return false;
}
}
template <class T>
void DLinkedList<T>::addToHead(T e)
{
Node<T> *ptrnode = new Node<T>(e,0,0);
if(isEmpty())
{
head = ptrnode;
tail = ptrnode;
}
else
{
ptrnode->ptrnext = head;
head->ptrprevious = ptrnode;
ptrnode->ptrprevious = 0;
head = ptrnode;
}
}
template <class T>
void DLinkedList<T>::addToTail(T e)
{
Node<T> *ptrnode = new Node<T>(e,0,0);
if(isEmpty())
{
head = ptrnode;
tail = ptrnode;
}
else
{
tail->ptrnext = ptrnode;
ptrnode->ptrprevious = tail;
ptrnode->ptrnext = 0;
tail = ptrnode;
}
}
template <class T>
void DLinkedList<T>::deleteFromHead()
{
if(!isEmpty())
{
if(head == tail)
{
delete head;
head = 0;
tail = 0;
}
else
{
Node<T> *ptrtemp = head;
head = head->ptrnext;
head->ptrprevious = 0;
delete ptrtemp;
}
}
}
template <class T>
void DLinkedList<T>::deleteFromTail()
{
if(!isEmpty())
{
if(head == tail)
{
delete tail;
head = 0;
tail = 0;
}
else
{
Node<T> *ptrtemp = tail;
tail = tail->ptrprevious;
tail->ptrnext = 0;
delete ptrtemp;
}
}
}
template <class T>
void DLinkedList<T>::display()
{
if(!isEmpty())
{
Node<T> *ptrtemp = head;
while(ptrtemp->ptrnext != 0)
{
cout<<ptrtemp->info;
ptrtemp = ptrtemp->ptrnext;
}
cout<<ptrtemp->info<<endl;
}
}
template <class T>
T DLinkedList<T>::getHead()
{
if(isEmpty())
{
return 0;
}
else
{
return head->info;
}
}
template <class T>
int DLinkedList<T>::numofNodes()
{
if(isEmpty())
{
return 0;
}
else
{
int count = 0;
Node<T> *ptrtemp = head;
while(ptrtemp->ptrnext != 0)
{
count++;
ptrtemp = ptrtemp->ptrnext;
}
count++;
return count;
}
}
template <class T>
class Stack:public DLinkedList<T>
{
private:
int maxStackSize;
public:
Stack()
{
maxStackSize = 10;
}
bool isEmpty();
bool isFull();
void Push(T e);
T Pop();
void display();
T topvalue();
};
template <class T>
bool Stack<T>::isEmpty()
{
bool r= DLinkedList<T>::isEmpty();
return r;
}
template <class T>
bool Stack<T>::isFull()
{
int totalNodes = DLinkedList<T>::numofNodes();
if(totalNodes == maxStackSize)
{
return true;
}
else
{
return false;
}
}
template <class T>
void Stack<T>::Push(T e)
{
if( isFull() )
{
cout<<"Stack Full "<<endl;
}
else
{
DLinkedList<T>::addToHead(e);
}
}
template <class T>
T Stack<T>::Pop()
{
if(isEmpty())
{
return 0;
}
else
{
T n = DLinkedList<T>::getHead();
DLinkedList<T>::deleteFromHead();
return n;
}
}
template <class T>
void Stack<T>::display()
{
if( isEmpty() )
{
cout<<"Stack Empty!!"<<endl;
}
else
{
DLinkedList<T>::display();
}
}
template<class T>
T Stack<T>::topvalue()
{
T temp;
temp=DLinkedList<T>::getHead();
return temp;
}
int main()
{
Stack<char> obj;
char input[20];
cout<<"Enter Values \n";
cin>>input;
int size= strlen(input);
for(int i=0; i <size ; i++)
{
//======= For + or - Operators=========
if(input[i]=='+' || input[i]=='-')
{
if(obj.topvalue()=='+' || obj.topvalue()=='-')
{ //======= CASE-1=======
cout<<obj.Pop();
obj.Push(input[i]);
}
else if(obj.topvalue()=='*' || obj.topvalue()=='/')
{
//======= CASE-2=========
cout<<obj.Pop();
if(obj.topvalue()=='*' || obj.topvalue()=='/')
{
cout<<obj.Pop();
}
obj.Push(input[i]);
}
else if(obj.topvalue()=='(')
{
//======= CASE-3=========
obj.Push(input[i]);
}
else if(obj.isEmpty())
{
//======= CASE-4=========
obj.Push(input[i]);
}
}
// ++++++++++ FOR * and / Operators ++++++++
else if(obj.topvalue()=='*' || obj.topvalue()=='/')
{
if(obj.topvalue()=='+' || obj.topvalue()=='-')
{
//======= CASE-1=========
cout<<obj.Pop();
obj.Push(input[i]);
}
else if(obj.isEmpty())
{
//======= CASE-2=========
obj.Push(input[i]);
}
else if(obj.topvalue()=='(')
{
//======= CASE-3=========
obj.Push(input[i]);
}
else
{
//======= CASE-4=========
obj.Push(input[i]);
}
}
// ++++++++++ Opening bracket ++++++++
else if (obj.topvalue()=='(')
{
obj.Push(input[i]);
}
// ++++++++++ Closing Bracket ++++++++
else if(input[i] != ')')
{
while(obj.topvalue() != '(')
{
cout<<obj.Pop();
}
obj.Pop();
}
// ++++++++++ Operands ++++++++
else
{
cout<<input[i];
}
}
// ++++++++++ Print All values from the Stack and empty it++++++++
while(!obj.isEmpty())
{
cout<<obj.Pop();
}
return 0;
}
>
You have made mistake in following line:
else if (input[i] != ')')
due to which the program is going into infinite loop.
It needs to be:
else if (input[i] == ')')

c++ how implement iterator for a doubly linked list

I am using this text book
http://cpp.datastructures.net
chapter 5 iterator usage:
http://cpp.datastructures.net/source/ch05/CPP/IteratorPrint.cpp-DSACiterator.html
here is how i implement it (the ObjectIterator class)
#include <iostream>
using namespace std;
class PositionException {
protected:
string message;
public:
PositionException(const string &m) {
message = m;
}
void print() {
cout << message << endl;
}
};
template <typename T>
class NodeList {
protected:
struct Node {
Node *prev;
Node *next;
T item;
Node(T i = T(), Node *p = NULL, Node *n = NULL) : item(i), prev(p), next(n) {}
};
typedef Node * NodePtr;
public:
class Position {
protected:
NodePtr node;
public:
bool isNull() {
return node == NULL;
}
Position(NodePtr n = NULL) : node(n) {}
T& element() {
return node->item;
}
friend class NodeList;
};
class ObjectIterator {
protected:
NodePtr node;
public:
ObjectIterator(NodePtr n = NULL) : node(n) {}
bool hasNext() {
if (node->next == NULL) {
return false;
}
if (node->next->next == NULL) {
return false;
}
return true;
}
ObjectIterator next() {
return ObjectIterator(node->next);
}
T& element() {
return node->item;
}
friend class NodeList;
};
protected:
int sz;
NodePtr header;
NodePtr trailer;
public:
NodeList() {
header = new Node();
trailer = new Node();
header->next = trailer;
trailer->prev = header;
sz = 0;
}
bool isEmpty() const {
return size() == 0;
}
int size() const {
return sz;
}
bool isFirst(const Position& p) const {
return p.node->prev == header;
}
bool isLast(const Position& p) const {
return p.node->next = trailer;
}
Position first() const {
if (isEmpty()) {
throw PositionException("no first for empty list");
}
return Position(header->next);
}
Position last() const {
if (isEmpty()) {
throw PositionException("no last for emtpy list");
}
return Position(trailer->prev);
}
Position before(const Position& p) const{
if (p.node->prev == header) {
throw PositionException("already the first element, nothing before it");
}
return Position(p.node->prev);
}
Position after(const Position& p) const{
if (p.node->next == trailer) {
throw PositionException("already the last element, nothing after it");
}
return Position(p.node->next);
}
Position insertAfter(const Position& p, const T& o) {
NodePtr node = new Node(o, p.node, p.node->next);
p.node->next->prev = node;
p.node->next = node;
sz++;
return Position(node);
}
Position insertBefore(const Position& p, const T& o) {
NodePtr node = new Node(o, p.node->prev, p.node);
p.node->prev->next = node;
p.node->prev = node;
sz++;
return Position(node);
}
void remove(const Position& p) {
p.node->prev->next = p.node->next;
p.node->next->prev = p.node->prev;
sz--;
delete p.node;
}
void removeFirst() {
remove(first());
}
void removeLast() {
remove(last());
}
void replaceElement(const Position& p, const T& element) {
if (p.isNull()) {
throw PositionException("p is null");
}
p.node->item = element;
}
Position insertFirst(const T& o) {
NodePtr node = new Node(o, header, header->next);
header->next->prev = node;
header->next = node;
sz++;
return Position(node);
}
Position insertLast(const T& o) {
NodePtr node = new Node(o, trailer->prev, trailer);
trailer->prev->next = node;
trailer->prev = node;
sz++;
return Position(node);
}
void copyFrom(const NodeList<T>& nl) {
sz = nl.sz;
if (nl.sz > 0) {
Position p0 = nl.first();
Position p = insertFirst(p0.node->item);
while (!nl.isLast(p0)) {
p0 = nl.after(p0);
insertAfter(p, p0.node->item);
}
}
}
void emptyList() {
while (!isEmpty()) {
removeFirst();
}
}
~NodeList() {
emptyList();
delete header;
delete trailer;
}
NodeList<T>& operator=(const NodeList<T>& nl) {
emptyList();
copyFrom(nl);
}
NodeList(const NodeList<T>& nl) {
emptyList();
copyFrom(nl);
}
void print() {
cout << "size is: " << size() << endl;
if (size() > 0) {
ObjectIterator i = elements();
while (i.hasNext()) {
cout << i.element() << "\t";
i = i.next();
}
cout << endl;
}
}
ObjectIterator elements() {
if (isEmpty()) {
throw PositionException("iterator error: empty");
}
return ObjectIterator(header->next);
}
void swapItems(const Position& p1, const Position& p2) {
T temp = p1.node->item;
p1.node->item = p2.node->item;
p2.node->item = temp;
}
};
If i don't use the iterator, the following code for printing is correct
void print() {
if (size() > 0) {
NodePtr n = header->next;
while (n != trailer) {
cout << n->item << "\t";
n = n->next;
}
cout << endl;
}
}
If I use the iterator for the print function
void print() {
cout << "size is: " << size() << endl;
if (size() > 0) {
ObjectIterator i = elements();
while (i.hasNext()) {
cout << i.element() << "\t";
i = i.next();
}
cout << endl;
}
}
one of the node is missing.
The book does not provide the correct way to implement the iterator

Invalid memory access when using binary research tree

Here is my codes.
#include<iostream>
template<class Elem>
class BinNode
{
public:
virtual Elem& getVal() = 0;
virtual void setVal(const Elem&) = 0;
virtual BinNode* left() = 0;
virtual BinNode* right() = 0;
virtual void setLeft(BinNode*) = 0;
virtual void setRight(BinNode*) = 0;
virtual bool isLeaf() = 0;
};//abstract class
template<class Elem>
class BinNodePtr:public BinNode<Elem>
{
public:
Elem val;
BinNodePtr* lc;
BinNodePtr* rc;
BinNodePtr()
{
lc = rc = NULL;
}
~BinNodePtr()
{
delete lc;
delete rc;
}
void setVal(const Elem& e)
{
val = e;
}
Elem& getVal()
{
return this->val;
}
void setLeft(BinNode<Elem>* e)
{
lc = (BinNodePtr<Elem>*)e;
}
void setRight(BinNode<Elem>* e)
{
rc = (BinNodePtr<Elem>*)e;
}
bool isLeaf()
{
if(this->lc == NULL && this->rc == NULL)
return true;
return false;
}
BinNodePtr<Elem>* left()
{
return lc;
}
BinNodePtr<Elem>* right()
{
return rc;
}
};
template<class Elem>
class BST
{
public:
BinNodePtr<Elem> *root;
int nodenum;
void deleteElem(BinNodePtr<Elem>* start);
void midorder(BinNodePtr<Elem>* start);
public:
BST()
{
root = NULL;
nodenum = 0;
}
~BST()
{
deleteElem(root);
}
bool insert(BinNodePtr<Elem>* ptr,const Elem &e);
BinNodePtr<Elem>* getRoot(){return root;}
};
template<class Elem>
void BST<Elem>::deleteElem(BinNodePtr<Elem>* start)
{
BinNodePtr<Elem>* temp =(BinNodePtr<Elem>*) start;
if(temp == NULL) return;
deleteElem((BinNodePtr<Elem>*)temp->left());
deleteElem((BinNodePtr<Elem>*)temp->right());
delete temp;
}
template<class Elem>
void BST<Elem>::midorder(BinNodePtr<Elem> *start)
{
if(start == NULL) return;
midorder(start->lc);
printf("%d ",start->getVal());
midorder(start->rc);
}
template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>*ptr,const Elem &e)
{
if(ptr == NULL)
{
ptr = new BinNodePtr<Elem>;
ptr->lc = NULL;
ptr->rc = NULL;
ptr->val = e;
return true;
}
else
{
if(ptr->val < e || ptr->val == e)
{
ptr = ptr->right();
insert(ptr->rc,e);
}
else
{
ptr = ptr->left();
insert(ptr->lc,e);
}
}
return false;
}
int main()
{
BST<int> myBST;
myBST.insert(myBST.root,10);
myBST.insert(myBST.root,20);
myBST.insert(myBST.root,5);
myBST.insert(myBST.root,30);
printf("%d",myBST.getRoot()->getVal());
system("pause");
return 0;
}
There are some functions which are not used in my program.I focus on the "insert" function.When I debug this ,the program breaks down at printf("%d",myBST.getRoot()->getVal());saying "invalid memory access",Why and how to solve it?
You have to remember that in C++ arguments are by default passed by value, that means their value is copied to the argument in the called function. When you change an argument in the function, you only change its local copy, no changes to the copy will be propagated to the caller.
To change an argument in the caller, you have to pass it by reference, like
bool insert(BinNodePtr<Elem>*& ptr,const Elem& e);
This will make the ptr argument a reference to the pointer, so changes to it will propagate to the caller.
If you want to change the ptr argument in the insert function, you should pass the address of it, like so:
template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>**ptr,const Elem &e)
or pass a reference to it.

Invalid use of incomplete type (class)

I am getting a few errors in my Binary Search Tree print code and I do not know why. (Errors at the bottom)
#ifndef MYBSTREE_H
#define MYBSTREE_H
#include "abstractbstree.h"
#include "abstractstack.h"
using namespace std;
class LinkedStack *head = NULL; //LINE 7
template<typename T>
class TreeNode
{
public:
T m_data;
TreeNode* m_right;
TreeNode* m_left;
};
template<typename T>
class LinkedStack: public AbstractStack<TreeNode<T>*>
{
public:
TreeNode<T>* m_data;
LinkedStack *m_next;
LinkedStack()
{
if(head != NULL)
head = new LinkedStack;
m_data = 0;
m_next = NULL;
}
void clear()
{
while(head -> m_next != NULL)
{
LinkedStack *tmp = head -> m_next;
head -> m_ldata= tmp -> m_ldata;
head -> m_next = tmp -> m_next;
delete tmp;
}
}
void push(TreeNode<T>* x)
{
LinkedStack *tmp = new LinkedStack;
tmp -> m_data = m_data;
tmp -> m_next = m_next;
m_data = x;
m_next = tmp;
}
void pop()
{
if (isEmpty())
cout<<"Panic! Nothing to pop"<<endl;
else
{
LinkedStack *tmp;
tmp = m_next;
m_data = tmp -> m_data;
m_next = tmp -> m_next;
delete tmp;
}
}
int& top()
{
if (isEmpty())
cout<<"Panic! List is Empty"<<endl;
return m_ldata;
}
bool isEmpty()
{
bool empty = false;
if (m_next == NULL)
{
empty = true;
}
return empty;
}
};
template<typename T>
class MyBSTree:public AbstractBSTree<T>
{
private:
TreeNode<T>* m_root;
public:
~MyBSTree()
{
clear();
}
MyBSTree()
{
m_root -> m_data = T();
m_root -> m_right = NULL;
m_root -> m_left = NULL;
};
int size() const
{
if(m_root==NULL)
return 0;
else
return (size(m_root->m_left)+1+size(m_root->m_right));
}
bool isEmpty() const
{
if (m_root== NULL)
return true;
else
return false;
}
int height() const
{
int lh,rh;
if(m_root==NULL)
{
return 0;
}
else
{
lh = height(m_root->m_left);
rh = height(m_root->m_right);
if(lh > rh)
return lh + 1;
else
return rh + 1;
}
}
const T& findMax() const
{
TreeNode<T>* p = m_root;
while(p -> m_right != NULL)
p = p -> m_right;
return p;
}
const T& findMin() const
{
TreeNode<T>* p = m_root;
while(p -> m_left != NULL)
p = p -> m_left;
return p;
}
/*
int contains(const T& x) const;
*/
void clear()
{
delete m_root;
}
void insert(const T& x)
{
TreeNode<T>* p = m_root;
do
{
if (x == p -> m_root)
return;
else if ( x < p->m_data)
{
if(p->m_left == NULL)
{
p->m_left = new TreeNode<T>;
p -> m_left -> m_data = x;
return;
}
else
p = p -> m_left;
}
else if( x > p->m_data)
{
if(p->m_right == NULL)
{
p->m_right = new TreeNode<T>;
p-> m_right -> m_data = x;
return;
}
else
p = p -> m_right;
}
}while(p -> m_right != NULL && p -> m_left != NULL);
}
void remove(const T& x)
{
if(m_root == NULL)
return;
TreeNode<T>* q = m_root;
TreeNode<T>* p;
while(q != NULL)
{
if(m_root->m_data == x)
{
delete q;
return;
}
else if(x > q->m_data)
{
p = q;
q = q->m_right;
}
else
{
p = q;
q = q->m_left;
}
}
if(q->m_left == NULL && q->m_right == NULL)
{
if(p == q)
delete p;
else if(p->m_left == q)
{
p->m_left = NULL;
delete q;
}
else
{
p->m_right = NULL;
delete q;
}
return;
}
if((q->m_left == NULL && q->m_right != NULL) || (q->m_left != NULL && q->m_right == NULL))
{
if(q->m_left == NULL && q->m_right != NULL)
{
if(p->m_left == q)
{
p->m_left = q->m_right;
delete q;
}
else
{
p->m_right = q->m_right;
delete q;
}
}
else
{
if(p->m_left == q)
{
p->m_left = q->m_left;
delete q;
}
else
{
p->m_right = q->m_left;
delete q;
}
}
return;
}
if (q->m_left != NULL && q->m_right != NULL)
{
TreeNode<T>* check;
check = q->m_right;
if((check->m_left == NULL) && (check->m_right == NULL))
{
q = check;
delete check;
q->m_right = NULL;
}
else
{
if((q->m_right)->m_left != NULL)
{
TreeNode<T>* m_leftq;
TreeNode<T>* m_leftp;
m_leftp = q->m_right;
m_leftq = (q->m_right)->m_left;
while(m_leftq->m_left != NULL)
{
m_leftp = m_leftq;
m_leftq = m_leftq->m_left;
}
q->data = m_leftq->data;
delete m_leftq;
m_leftp->m_left = NULL;
}
else
{
TreeNode<T>* tmp;
tmp = q->m_right;
q->data = tmp->data;
q->m_right = tmp->m_right;
delete tmp;
}
}
return;
}
}
void printPreOrder() const
{
LinkedStack stack;
stack<T>.push(m_root); //THIS LINE
while(!stack.isEmpty()) //THIS LINE
{
TreeNode<T>* root = stack.push(); //THIS LINE
stack.pop(); //THIS LINE
if(root!= NULL)
{
stack.push(root->right); //THIS LINE
stack.push(root->m_left); //THIS LINE
cout << root->m_data << " ";
}
}
}
/*
void printPostOrder() const;
void print() const;
*/
};
#endif
What I am getting are errors that say:
MyBSTree.h: In member function âvoid MyBSTree<T>::printPreOrder() constâ:
MyBSTree.h:362:9: error: invalid use of incomplete type âstruct LinkedStackâ
MyBSTree.h:7:7: error: forward declaration of âstruct LinkedStackâ
I get that for all the lines I have marked in that particular function. I'm pretty sure it has something to do with template syntax, but I'm not sure.
Line class LinkedStack *head = NULL; has no sense. If you want to have a head to your LinkedStack, you should:
drop the class in this line
pass correct type since it's a template
do it after the templated class definition
Something like this: LinkedStack<your type> *head = NULL;
I don't understande what you mean by
class LinkedStack *head = NULL; //LINE 7
Is this supposed to be the forward declaration? in this case it should be
template<typename T>
class LinkedStack;
If after that you are trying to initialize an instance, then it should be
LinkedStack<int> *head = NULL; //int as a typename T
but you can't mix both in one line :)