I'm making a simple linked list with a classic functions. The elements in this list should not be repeated and should be in an order. The function find recieves two parameters: The valor that should be finded and the pointer to save the node that has it. Everything is going well, but the pointer keeps being nullptr because is not saving the current memory address. I can't understand why my pointer is not pointing to the current node. Please Help me.
template <class T>
class simpleNode {
public:
T data;
simpleNode<T>* next = NULL;
simpleNode(T newData) {
data = newData;
}
};
template <class T, class C>
class simpleLinkedListOnePointer {
public:
simpleNode<T>* head;
C comparator;
simpleLinkedListOnePointer <T, C>() {
head = NULL;
}
bool find(T x, simpleNode<T>*& p) {
p = head;
while (p && comparator(p->data, x))
p = p->next;
return p?true:false;
}
bool insert(T x) {
simpleNode<T>* ptr;
if (find(x, ptr)) {
return false;
}
simpleNode<T>* ptrAdd = new simpleNode<T>(x);
if (!ptr) {
ptrAdd->next = head;
head = ptrAdd;
return true;
}
else {
cout << "ESTE ES EL NODO APUNTADO POR PTR: " << ptr->data << endl;
ptrAdd->next = ptr->next;
ptr->next = ptrAdd;
return true;
}
}
bool remove(T x) {
return 1;
}
void print() {
simpleNode<T>* p = head;
while (p) {
cout << p->data << "->";
p = p->next;
}
cout << endl;
}
};```
Compiler says segmentation fault but doesn't tell me which line. From what I understand, a segmentation fault usually means a value at address NULL was attempted to be accessed, but I do not see where that's happening.
#include <iostream>
template <typename T> class SinglyLinkedList
{
struct node
{
T val;
node * next;
};
public:
SinglyLinkedList ();
SinglyLinkedList (T *, size_t);
~SinglyLinkedList ();
void push_back (T);
void print ();
private:
node * _root;
};
int main ()
{
int myArray [] = { 1, 69, -23942, 11111 };
SinglyLinkedList<int> myList(myArray, sizeof(myArray)/sizeof(int));
myList.print();
return 0;
}
template <typename T> SinglyLinkedList<T>::SinglyLinkedList ( )
{
_root = NULL;
}
template <typename T> SinglyLinkedList<T>::SinglyLinkedList (T * arr, size_t n)
{
/* Initialize a singly-linked list of objects of type T from an array of objects of type T */
if (n > 0)
{
node * lastNode = new node;
lastNode->val = *arr;
lastNode->next = NULL;
for (T * pa(arr+1), * pb(arr+n); pa != pb; ++pa)
{
node * thisNode = new node;
thisNode->val = *pa;
thisNode->next = NULL;
lastNode->next = thisNode;
lastNode = thisNode;
}
delete lastNode;
}
else
{
_root = NULL;
}
}
template <typename T> SinglyLinkedList<T>::~SinglyLinkedList ( )
{
node * thisNode = _root;
while (thisNode != NULL)
{
node * temp = thisNode;
thisNode = thisNode->next;
delete temp;
}
}
template <typename T> void SinglyLinkedList<T>::print ( )
{
if (_root == NULL) return;
for (node * thisNode = _root; thisNode != NULL; thisNode = thisNode->next)
{
std::cout << thisNode->val << "->";
}
std::cout << "NULL";
}
Your constructor is wrong.
If n>0 (as in this case) you do a lot of pointer-pointing (which doesn't do what you think it does), but assign no value to _root. Then in print() you dereference _root, which does not point to a valid object; you're lucky all you get is a seg fault.
I am using Visiual Studio 2013. For some reason, I am getting the following error:
Error 1 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Word &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#AAVWord###Z) referenced in function "protected: virtual void __thiscall BST<class Word>::visit(class BSTNode<class Word> *)" (?visit#?$BST#VWord####MAEXPAV?$BSTNode#VWord#####Z) C:\Users\Reuben\documents\visual studio 2013\Projects\CS321 Lab4\CS321 Lab4\main.obj CS321 Lab4
The error is due to this particular line:
BST<Word> tree;
If the line were as follows, then it seems to compile just fine:
BST<int> tree;OR BST<string> tree;
So for some reason, it's not liking my implementation of the Word class I defined. Here is the following code.
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Word.h"
#include "genBST.h"
using namespace std;
int main()
{
BST<Word> tree;
system("pause");
return 0;
}
Word.h
#include <string>
#include <set>
using namespace std;
class Word{
public:
string* word;
set<int>* lineNums;
void addLineNum(int);
Word(string*, int);
Word();
friend ostream& operator<<(ostream& out, Word& pr);
friend bool operator==(Word, Word);
friend bool operator!=(Word, Word);
friend bool operator<(Word, Word);
friend bool operator<=(Word, Word);
friend bool operator>=(Word, Word);
friend bool operator>(Word, Word);
};
Word::Word(string* myWord, int myLineNum) {
word = myWord;
set<int>* lineNums = new set<int>();
lineNums->insert(myLineNum);
}
Word::Word()
{
word = new string("");
set<int>* lineNums = new set<int>();
lineNums->insert(1);
}
void Word::addLineNum(int line)
{
lineNums->insert(line);
}
//overload comparison operators
//take note that the order of these are important
//since some of the operators are defined in terms of the previously defined ones
bool operator==(Word word1, Word word2)
{
if (*(word1.word) == *(word2.word))
{
return true;
}
return false;
}
bool operator!=(Word word1, Word word2)
{
return !(word1 == word2);
}
bool operator<=(Word word1, Word word2)
{
if (*(word1.word) <= *(word2.word))
{
return true;
}
return false;
}
bool operator<(Word word1, Word word2)
{
if (word1 <= word2 && word1 != word2)
return true;
return false;
}
bool operator>(Word word1, Word word2)
{
return !(word1 <= word2);
}
bool operator>=(Word word1, Word word2)
{
return !(word1 < word2);
}
std::ostream& operator<<(std::ostream& out, const Word& word1)
{
out << *(word1.word);
out << ": ";
set<int>::iterator it;
for (it = word1.lineNums->begin(); it != word1.lineNums->end(); it++)
{
out << *it << " ";
}
return out;
}
The last file is genBST.h. It's a long file, so I'm posting it last. This file was given to me as part of my assignment and we are not allowed to make changes to this file or else we will lose points.
//************************ genBST.h **************************
// generic binary search tree
#include <queue>
#include <stack>
#ifndef BINARY_SEARCH_TREE
#define BINARY_SEARCH_TREE
template<class T>
class Stack : public stack<T> {
public:
T pop() {
T tmp = top();
stack<T>::pop();
return tmp;
}
};
template<class T>
class Queue : public queue<T> {
public:
T dequeue() {
T tmp = front();
queue<T>::pop();
return tmp;
}
void enqueue(const T& el) {
push(el);
}
};
template<class T> class BST;
template<class T>
class BSTNode {
public:
BSTNode() {
left = right = 0;
}
BSTNode(const T& e, BSTNode<T> *l = 0, BSTNode<T> *r = 0) {
el = e; left = l; right = r;
}
T el;
BSTNode<T> *left, *right;
};
template<class T>
class BST {
public:
BST() {
root = 0;
}
~BST() {
clear();
}
void clear() {
clear(root);
root = 0;
}
bool isEmpty() const {
return root == 0;
}
void preorder() {
preorder(root);
}
void inorder() {
inorder(root);
}
void postorder() {
postorder(root);
}
void insert(const T&);
void recursiveInsert(const T& el) {
recursiveInsert(root, el);
}
T* search(const T& el) const {
return search(root, el);
}
T* recursiveSearch(const T& el) const {
return recursiveSearch(root, el);
}
void deleteByCopying(BSTNode<T>*&);
void findAndDeleteByCopying(const T&);
void deleteByMerging(BSTNode<T>*&);
void findAndDeleteByMerging(const T&);
void iterativePreorder();
void iterativeInorder();
void iterativePostorder();
void breadthFirst();
void MorrisPreorder();
void MorrisInorder();
void MorrisPostorder();
void balance(T*, int, int);
protected:
BSTNode<T>* root;
void clear(BSTNode<T>*);
void recursiveInsert(BSTNode<T>*&, const T&);
T* search(BSTNode<T>*, const T&) const;
T* recursiveSearch(BSTNode<T>*, const T&) const;
void preorder(BSTNode<T>*);
void inorder(BSTNode<T>*);
void postorder(BSTNode<T>*);
virtual void visit(BSTNode<T>* p)
{
cout << p->el << ' ';
}
};
template<class T>
void BST<T>::clear(BSTNode<T> *p) {
if (p != 0) {
clear(p->left);
clear(p->right);
delete p;
}
}
template<class T>
void BST<T>::insert(const T& el) {
BSTNode<T> *p = root, *prev = 0;
while (p != 0) { // find a place for inserting new node;
prev = p;
if (el < p->el)
p = p->left;
else p = p->right;
}
if (root == 0) // tree is empty;
root = new BSTNode<T>(el);
else if (el < prev->el)
prev->left = new BSTNode<T>(el);
else prev->right = new BSTNode<T>(el);
}
template<class T>
void BST<T>::recursiveInsert(BSTNode<T>*& p, const T& el) {
if (p == 0)
p = new BSTNode<T>(el);
else if (el < p->el)
recursiveInsert(p->left, el);
else recursiveInsert(p->right, el);
}
template<class T>
T* BST<T>::search(BSTNode<T>* p, const T& el) const {
while (p != 0)
if (el == p->el)
return &p->el;
else if (el < p->el)
p = p->left;
else p = p->right;
return 0;
}
template<class T>
T* BST<T>::recursiveSearch(BSTNode<T>* p, const T& el) const {
if (p != 0)
if (el == p->el)
return &p->el;
else if (el < p->el)
return recursiveSearch(p->left, el);
else return recursiveSearch(p->right, el);
else return 0;
}
template<class T>
void BST<T>::inorder(BSTNode<T> *p) {
if (p != 0) {
inorder(p->left);
visit(p);
inorder(p->right);
}
}
template<class T>
void BST<T>::preorder(BSTNode<T> *p) {
if (p != 0) {
visit(p);
preorder(p->left);
preorder(p->right);
}
}
template<class T>
void BST<T>::postorder(BSTNode<T>* p) {
if (p != 0) {
postorder(p->left);
postorder(p->right);
visit(p);
}
}
template<class T>
void BST<T>::deleteByCopying(BSTNode<T>*& node) {
BSTNode<T> *previous, *tmp = node;
if (node->right == 0) // node has no right child;
node = node->left;
else if (node->left == 0) // node has no left child;
node = node->right;
else {
tmp = node->left // node has both children;
previous = node; // 1.
while (tmp->right != 0) { // 2.
previous = tmp;
tmp = tmp->right;
}
node->el = tmp->el; // 3.
if (previous == node)
previous->left = tmp->left;
else previous->right = tmp->left; // 4.
}
delete tmp; // 5.
}
// findAndDeleteByCopying() searches the tree to locate the node containing
// el. If the node is located, the function DeleteByCopying() is called.
template<class T>
void BST<T>::findAndDeleteByCopying(const T& el) {
BSTNode<T> *p = root, *prev = 0;
while (p != 0 && !(p->el == el)) {
prev = p;
if (el < p->el)
p = p->left;
else p = p->right;
}
if (p != 0 && p->el == el)
if (p == root)
deleteByCopying(root);
else if (prev->left == p)
deleteByCopying(prev->left);
else deleteByCopying(prev->right);
else if (root != 0)
cout << "el " << el << " is not in the tree\n";
else cout << "the tree is empty\n";
}
template<class T>
void BST<T>::deleteByMerging(BSTNode<T>*& node) {
BSTNode<T> *tmp = node;
if (node != 0) {
if (!node->right) // node has no right child: its left
node = node->left; // child (if any) is attached to its parent;
else if (node->left == 0) // node has no left child: its right
node = node->right; // child is attached to its parent;
else { // be ready for merging subtrees;
tmp = node->left; // 1. move left
while (tmp->right != 0)// 2. and then right as far as possible;
tmp = tmp->right;
tmp->right = // 3. establish the link between the
node->right; // the rightmost node of the left
// subtree and the right subtree;
tmp = node; // 4.
node = node->left; // 5.
}
delete tmp; // 6.
}
}
template<class T>
void BST<T>::findAndDeleteByMerging(const T& el) {
BSTNode<T> *node = root, *prev = 0;
while (node != 0) {
if (node->el == el)
break;
prev = node;
if (el < node->el)
node = node->left;
else node = node->right;
}
if (node != 0 && node->el == el)
if (node == root)
deleteByMerging(root);
else if (prev->left == node)
deleteByMerging(prev->left);
else deleteByMerging(prev->right);
else if (root != 0)
cout << "el " << el << " is not in the tree\n";
else cout << "the tree is empty\n";
}
template<class T>
void BST<T>::iterativePreorder() {
Stack<BSTNode<T>*> travStack;
BSTNode<T> *p = root;
if (p != 0) {
travStack.push(p);
while (!travStack.empty()) {
p = travStack.pop();
visit(p);
if (p->right != 0)
travStack.push(p->right);
if (p->left != 0) // left child pushed after right
travStack.push(p->left); // to be on the top of the stack;
}
}
}
template<class T>
void BST<T>::iterativeInorder() {
Stack<BSTNode<T>*> travStack;
BSTNode<T> *p = root;
while (p != 0) {
while (p != 0) { // stack the right child (if any)
if (p->right) // and the node itself when going
travStack.push(p->right); // to the left;
travStack.push(p);
p = p->left;
}
p = travStack.pop(); // pop a node with no left child
while (!travStack.empty() && p->right == 0) { // visit it and all nodes
visit(p); // with no right child;
p = travStack.pop();
}
visit(p); // visit also the first node with
if (!travStack.empty()) // a right child (if any);
p = travStack.pop();
else p = 0;
}
}
template<class T>
void BST<T>::iterativePostorder() {
Stack<BSTNode<T>*> travStack;
BSTNode<T>* p = root, *q = root;
while (p != 0) {
for (; p->left != 0; p = p->left)
travStack.push(p);
while (p->right == 0 || p->right == q) {
visit(p);
q = p;
if (travStack.empty())
return;
p = travStack.pop();
}
travStack.push(p);
p = p->right;
}
}
template<class T>
void BST<T>::breadthFirst() {
Queue<BSTNode<T>*> queue;
BSTNode<T> *p = root;
if (p != 0) {
queue.enqueue(p);
while (!queue.empty()) {
p = queue.dequeue();
visit(p);
if (p->left != 0)
queue.enqueue(p->left);
if (p->right != 0)
queue.enqueue(p->right);
}
}
}
template<class T>
void BST<T>::MorrisInorder() {
BSTNode<T> *p = root, *tmp;
while (p != 0)
if (p->left == 0) {
visit(p);
p = p->right;
}
else {
tmp = p->left;
while (tmp->right != 0 &&// go to the rightmost node of
tmp->right != p) // the left subtree or
tmp = tmp->right; // to the temporary parent of p;
if (tmp->right == 0) { // if 'true' rightmost node was
tmp->right = p; // reached, make it a temporary
p = p->left; // parent of the current root,
}
else { // else a temporary parent has been
visit(p); // found; visit node p and then cut
tmp->right = 0; // the right pointer of the current
p = p->right; // parent, whereby it ceases to be
} // a parent;
}
}
template<class T>
void BST<T>::MorrisPreorder() {
BSTNode<T> *p = root, *tmp;
while (p != 0) {
if (p->left == 0) {
visit(p);
p = p->right;
}
else {
tmp = p->left;
while (tmp->right != 0 &&// go to the rightmost node of
tmp->right != p) // the left subtree or
tmp = tmp->right; // to the temporary parent of p;
if (tmp->right == 0) { // if 'true' rightmost node was
visit(p); // reached, visit the root and
tmp->right = p; // make the rightmost node a temporary
p = p->left; // parent of the current root,
}
else { // else a temporary parent has been
tmp->right = 0; // found; cut the right pointer of
p = p->right; // the current parent, whereby it ceases
} // to be a parent;
}
}
}
template<class T>
void BST<T>::MorrisPostorder() {
BSTNode<T> *p = new BSTNode<T>(), *tmp, *q, *r, *s;
p->left = root;
while (p != 0)
if (p->left == 0)
p = p->right;
else {
tmp = p->left;
while (tmp->right != 0 &&// go to the rightmost node of
tmp->right != p) // the left subtree or
tmp = tmp->right; // to the temporary parent of p;
if (tmp->right == 0) { // if 'true' rightmost node was
tmp->right = p; // reached, make it a temporary
p = p->left; // parent of the current root,
}
else { // else a temporary parent has been found;
// process nodes between p->left (included) and p (excluded)
// extended to the right in modified tree in reverse order;
// the first loop descends this chain of nodes and reverses
// right pointers; the second loop goes back, visits nodes,
// and reverses right pointers again to restore the pointers
// to their original setting;
for (q = p->left, r = q->right, s = r->right;
r != p; q = r, r = s, s = s->right)
r->right = q;
for (s = q->right; q != p->left;
q->right = r, r = q, q = s, s = s->right)
visit(q);
visit(p->left); // visit node p->left and then cut
tmp->right = 0; // the right pointer of the current
p = p->right; // parent, whereby it ceases to be
} // a parent;
}
}
template<class T>
void BST<T>::balance(T data[], int first, int last) {
if (first <= last) {
int middle = (first + last) / 2;
insert(data[middle]);
balance(data, first, middle - 1);
balance(data, middle + 1, last);
}
}
#endif
Any help would be appreciated! I'm still learning the basics of c++, I transferred schools so I'm trying to learn c++ (as opposed to Java which is what I was doing before at my other school). Thanks in advance!
EDIT: Oops, I was being dumb, the following line of code:
friend ostream& operator<<(ostream& out, Word& pr);
Should be (I think):
friend ostream& operator<<(ostream, const Word);
However, after this change, I still get the following error:
Error 1 error C2593: 'operator <<' is ambiguous c:\users\reuben\documents\visual studio 2013\projects\cs321 lab4\cs321 lab4\genbst.h 105 1 CS321 Lab4
Where the line 105 refers is the statement in the function (in the genBST.h file):
virtual void visit(BSTNode<T>* p)
{
cout << p->el << ' ';
}
EDIT v2:
Ok, I've changed the code and it seems to work now. I just placed the implementation of the << operator inside the declaration like so:
class Word{
public:
string* word;
set<int>* lineNums;
void addLineNum(int);
Word(string*, int);
Word();
friend ostream& operator<<(ostream& out, const Word& word1 )
{
out << *(word1.word);
out << ": ";
set<int>::iterator it;
for (it = word1.lineNums->begin(); it != word1.lineNums->end(); it++)
{
out << *it << " ";
}
return out;
};
friend bool operator==(Word, Word);
friend bool operator!=(Word, Word);
friend bool operator<(Word, Word);
friend bool operator<=(Word, Word);
friend bool operator>=(Word, Word);
friend bool operator>(Word, Word);
};
And it seems to work now.
I noticed that in your class definition you have:
class Word{
public:
string* word;
set<int>* lineNums;
void addLineNum(int);
Word(string*, int);
Word();
friend ostream& operator<<(ostream& out, Word& pr);
there is no const before Word & pr
however later in your code you have:
std::ostream& operator<<(std::ostream& out, const Word& word1)
see , there is a const here before Word& word1
should make them same( both have const), I think
I tried your code on my Visual Stdio 2010 ( I do not have 2013).
Before I adding the keyword const (before Word & pr) I got same error as you.
However, after I added the const, it was built successfully.
What is the error you got after you add the keyword const ? Post in detail here.
My question is why do I need to dereference and reference a pointer for the following code to work? Doesn't ref/deref cancel each other?
I would really appreciate if anyone could explain it like I'm five :)
Code:
template <typename T>
class binNode {
private:
T key;
public:
binNode * left;
binNode * right;
binNode * parent;
binNode() {
this->left = NULL;
this->right = NULL;
this->parent = NULL;
}
// arg constructor:
binNode (T key) {
this->key = key;
this->left = NULL;
this->right = NULL;
this->parent = NULL;
}
T getKey() {
return this->key;
}
void setKey(T key) {
this->key = key;
}
};
template<typename T> class Tree {
private:
binNode <T> *root;
public:
Tree() {
this->root = NULL;
}
Tree(binNode <T> * node) {
node->parent = NULL;
this->root = node;
}
/* THIS IS THE PART I DON'T GET */
void addNode(binNode<T> *&x, binNode<T> * node) { // what's up with the *&???
if (x == NULL) {
x = node;
return;
} else if (x->getKey() == node->getKey()) {
node->left = x;
node->parent = x->parent;
x->parent = node;
return;
}
if (node->getKey() < x->getKey()) {
addNode(x->left, node);
} else {
addNode(x->right, node);
}
}
void addNode(binNode<T> * node) {
addNode(this->root, node);
}
binNode<T> * treeSearch(binNode<T> * x, T key) {
if (x == NULL || key == x->getKey()) {
return x;
}
if (key < x->getKey()) {
return treeSearch(x->left, key);
} else {
return treeSearch(x->right, key);
}
}
void printOrdered() {
inorderTreeWalk(root);
cout << endl;
}
void inorderTreeWalk(binNode<T> * node) {
if (node != NULL) {
inorderTreeWalk(node->left);
cout << node->getKey() << '\t';
inorderTreeWalk(node->right);
}
}
};
Here is the main function (#inlude is not included)
int main() {
Tree<int> T (new binNode<int>(10));
// Tree<int> T = new binNode<int>(10);
T.addNode(new binNode<int> (11));
T.addNode(new binNode<int> (9));
T.addNode(new binNode<int> (8));
T.addNode(new binNode<int> (12));
T.printOrdered();
}
That's not a reference / dereference of a pointer, it's a reference to a pointer. It is necessary because...
void addNode(binNode<T> *&x, binNode<T> * node) {
if (x == NULL) {
x = node; // ...here...
return;
} else // ...
...you are assigning to the parameter x.
If you hadn't passed the pointer x by reference, you would assign to the local copy of the parameter:
void addNode(binNode<T> * x, binNode<T> * node) {
if (x == NULL) {
x = node; // this acts on the local copy only, and thus does nothing.
return;
} else // ...
Via the pointer (without the reference), you get a local copy of the address. Which means you can manipulate the value behind the pointer (in this case *x) which would change. But if you change the address itself, the address would behave like a local copy and you lose the address-changes after leaving the method.
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 :)