Invalid use of incomplete type (class) - c++

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 :)

Related

Doubly Linked List fails to add or delete valid entries

I've run it many times. I tried fixing my deleteNode() and addNode(), but it did not work. The output showed me that it failed to add some valid entries in my list, which resulted in failing to delete these valid entries. Someone please help me find the errors... I think either my isEmpty() is wrong or the addNode got messed up.
// Add nodes and makes it work in any cases: backward/forward
bool LinkedList::addNode(int id, string str) {
bool result = false;
if (id >= 0 && !(idExists(id))) {
Node *current = head;
Node *temp = new Node;
temp->data.data = str;
temp->data.id = id;
temp->forward = NULL;
temp->back = NULL;
// Kinds of adding cases
if(head == NULL) { // Check if list is empty
addHead(temp, current);
result = true;
} else {
while(temp->data.id > current->data.id && current->forward != NULL) {
current = current->forward;
}
// Backward
if(current->back == NULL) {
if(temp->data.id > current->data.id) {
if(current->forward == NULL) {
addTail(temp, current);
} else {
addMiddle(temp, current);
}
} else {
addHead(temp, current);
}
result = true;
// Forward
}else if(current->forward == NULL) {
if (temp->data.id > current->data.id) {
addTail(temp, current);
} else {
addMiddle(temp, current);
}
result = true;
}else {
if(temp->data.id > current->data.id) {
addMiddle(temp, current);
result = true;
}
}
}
}
return result;
}
void LinkedList::addHead(Node *temp, Node *current) {
if (head != NULL){
temp->forward = current;
current->back = temp;
head = temp;
} else {
head = temp;
}
}
void LinkedList::addMiddle(Node *temp, Node *current) {
temp->forward = current;
temp->back = current->back;
current->back->forward = temp;
current->back = temp;
}
void LinkedList::addTail(Node *temp, Node *current) {
current->forward = temp;
temp->back = current;
}
// Delete list
bool LinkedList::deleteNode(int id){
bool result = false;
if (idExists(id)) {
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
if (current->data.id == id && current->forward == NULL) {
if (current->back == NULL) { // Delete head
delete current;
head = NULL;
} else { // delete tail
deleteTail(current);
}
result = true;
} else if (current->data.id == id) {
if (current->back == NULL)
deleteHead(current);
else // delete middle
deleteMiddle(current);
result = true;
}
}
return result;
}
// Helper delete functions
void LinkedList::deleteHead(Node *current) {
head = current->forward;
head->back = NULL;
delete current;
}
void LinkedList::deleteMiddle(Node *current) {
current->back->forward = current->forward;
current->forward->back = current->back;
delete current;
}
void LinkedList::deleteTail(Node *current) {
current->back->forward = NULL;
delete current;
}
bool LinkedList::getNode(int id, Data *data) {
bool didGetNode = false;
if (idExists(id)) {
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
data->id = current->data.id;
data->data = current->data.data;
didGetNode = true;
}
return didGetNode;
}
// Check whether or not the id exists
bool LinkedList::idExists(int id){
bool exists = false;
if (head != NULL){
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
if (current->data.id == id) {
exists = true;
}
}
return exists;
}
You probably want to be passing a pointer to a pointer (**) or a pointer to a reference (*&) in functions where you are wanting to make a change to what the address of the node is containing. I hope that this helps you visualize it.
For example:
struct Node { };
void setNull1(Node* temp)
{
temp = nullptr;
}
void setNull2(Node** temp)
{
(*temp) = nullptr;
}
void setNull3(Node*& temp)
{
temp = nullptr;
}
int main()
{
Node* tmp = new Node;
setNull1(tmp);
if (tmp == nullptr)
{
cout << "NULLPTR";
} // tmp is not nullptr
Node* tmp1 = new Node;
setNull2(&tmp1);
if (tmp1 == nullptr)
{
cout << "NULLPTR";
} // tmp1 is nullptr
Node* tmp2 = new Node;
setNull3(tmp2);
if (tmp2 == nullptr)
{
cout << "NULLPTR";
} // tmp2 is nullptr
}
You should also consider writing nullptr instead of NULL.

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

Linked List Copy/Move semantic C++

so I have this code for linked list below. I need to create copy/move constructors and operators.
I am having troubles how to make it the right way.
I know the code isn't perfect, I will appreciate all tips, but I want to focus mainly on copy/move semantic.
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
class List {
class Node {
Node* next;
string text;
int index;
friend class List;
public:
Node(const string& value, int i) : next(nullptr), index(i), text(value) {}
friend ostream& operator<< (ostream& wy, const Node& wzl) {
if (wzl.next) return wy << wzl.text << ", " << *wzl.next;
else return wy << wzl.text;
}
};
Node* head;
int _size(Node* node, int size = 0) {
if (node == NULL) {
return size;
} else {
_size(node->next, size+1);
}
}
void _insert(Node* node, const string& value, int index) {
if (node->next == NULL || node->next->index > index) {
if (node->index == index) {
node->text = value;
} else {
Node* element = new Node(value, index);
element->next = node->next;
node->next = element;
}
} else {
_insert(node->next, value, index);
}
}
string _read(Node* node, int index) {
if (node->next != NULL && node->next->index <= index) {
return _read(node->next, index);
} else if (node->index == index) {
return node->text;
} else {
throw invalid_argument("No such index");
}
}
void _remove(Node* node, int index) {
if (node->next != NULL && node->next->index < index) {
_remove(node->next, index);
} else if (node->next->index == index) {
Node* temp;
if (node->next->next != NULL) {
int temp_index = node->next->next->index;
temp = new Node(node->next->next->text, temp_index);
if (node->next->next->next != NULL) {
temp->next = node->next->next->next;
} else {
temp->next = NULL;
}
temp->index = node->next->next->index;
} else {
temp = nullptr;
}
delete node->next;
node->next = temp;
} else {
throw invalid_argument("No such index");
}
}
public:
List() : head(nullptr){};
List(const List &lst) : head(nullptr) {
Node* tmp_lst = lst.head;
Node* tmp_this = this->head;
while (tmp_lst != NULL) {
// cerr << this->head->text;
tmp_this = new Node(tmp_lst->text, tmp_lst->index);
tmp_this = tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
List(List&& lst);
List(initializer_list<string> lst) : List() {
Node* tmp;
int pos = 0;
for (auto element : lst) {
if (this->head != NULL){
tmp->next = new Node(element, pos);
tmp = tmp->next;
pos++;
} else {
this->head = new Node(element, pos);
tmp = this->head;
pos++;
}
}
};
List& operator= (const List& lst) {
if (this != &lst) {
delete this->head;
this->head = nullptr;
Node* tmp_lst = lst.head;
Node* tmp_this = this->head;
while (tmp_lst != NULL) {
tmp_this = new Node(tmp_lst->text, tmp_lst->index);
tmp_this = tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
return *this;
}
List& operator= (List&& lst);
~List(){
delete head;
};
void insert(const string& value, int pos) {
if (pos < 0) {
throw invalid_argument("Position cant be negative");
}
if (this->head == NULL) {
Node* new_head = new Node(value, pos);
this->head = new_head;
} else if (this->head->index > pos) {
Node* new_head = new Node(value, pos);
new_head->next = this->head;
this->head = new_head;
} else {
_insert(this->head, value, pos);
}
}
string read(int pos) {
return _read(this->head, pos);
}
int size() {
return _size(this->head);
}
void remove(int pos) {
return _remove(this->head, pos);
}
public:
friend ostream& operator<< (ostream& wy, const List& lst) {
if (lst.head) return wy << "(" << *lst.head << ")";
else return wy << "()";
}
};
int main() {
return 0;
}
You List copy-constructor is severely flawed:
You initialize tmp_this to the value of this->head which is a null pointer
The above doesn't matter because the first thing you do in the loop is reassign tmp_this to point to a new Node object.
Then you immediately discard that pointer, by reassigning tmp_this to point to tmp_this->next which is a null pointer.
And you don't link anything into the list.
A working function could look something like
List(const List &lst) : head(nullptr) {
Node* tmp_lst = lst.head;
Node** tmp_current = &head;
while (tmp_lst != NULL) {
Node* tmp_this = new Node(tmp_lst->text, tmp_lst->index);
// Would prefer to use the copy-constructor here too, instead of the above
// Node* tmp_this = new Node(tmp_lst);
// This links the new node into the end of the list
*tmp_current = tmp_this
tmp_current = &tmp_this->next;
tmp_lst = tmp_lst->next;
}
}

C++ Templated Friend Classes

I am working in c++. I'm attempting to make my own iterator for a templated linked list class (without using the STL), but I seem to have trouble using "friends." I want to OListIterator to have access to the "Node" struct within the list class. If anyone could help it would be greatly appreciated!
OListIterator:
#ifndef pg6ec_OListIterator_h
#define pg6ec_OListIterator_h
#include "OList.h"
template <typename T>
class OListIterator
{
private:
T * value;
T * next;
public:
OListIterator()
{}
void setValue(T & val, T & n)
{
value = &val;
next = &n;
}
int operator*()
{
return *value;
}
bool operator==(OListIterator<T> other)
{
return value == other.value && next == other.next;
}
bool operator!=(OListIterator<T> other)
{
return value != other.value && next != other.next;
}
void operator+=(int x)
{
}
};
#endif
List:
#ifndef pg6OList_OListBlah_h
#define pg6OList_OListBlah_h
#include <stdio.h>
#include <stdlib.h>
#include "OListIterator.h"
template <typename T>
class list
{
private:
typedef struct node
{
T value;
struct node * next;
}Node;
Node * root;
public:
list()
{
root = NULL;
}
list(const list & other)
{
Node * temp = other.returnRoot();
Node * currSpot = NULL;
root = new Node;
root->value = temp->value;
currSpot = root;
temp = temp->next;
while (temp)
{
currSpot->next = new Node;
currSpot = currSpot->next;
currSpot->value = temp->value;
temp = temp->next;
}
}
~list()
{
clear();
};
void clear()
{
Node * delNode = root;
while (delNode)
{
root = root->next;
delete delNode;
delNode = root;
}
delete root;
};
Node * returnRoot() const
{
return this->root;
}
int size()
{
int ans = 0;
if (root == NULL)
{
return ans;
}
Node * top = root;
while (top)
{
ans++;
top = top->next;
}
return ans;
}
bool insert(T & item)
{
if (root == NULL)
{
root = new Node;
root->value = item;
return true;
}
else
{
Node * curr = root;
Node * prev = NULL;
while (curr)
{
if ( curr->value > item )
{
Node * insertion = new Node;
insertion->value = item;
if (prev)
{
insertion->next = curr;
prev->next = insertion;
}
else
{
root = insertion;
root->next = curr;
}
return true;
}
else if ( curr->value == item )
{
Node * insertion = new Node;
insertion->value = item;
insertion->next = curr->next;
curr->next = insertion;
return true;
}
prev = curr;
if (curr->next)
{
curr = curr->next;
}
else if ( curr->next == NULL )
{
curr->next = new Node;
curr->next->next = NULL;
curr->next->value = item;
return true;
}
}
}
return false;
}
T get(int x)
{
T ans = root->value;
if (x > size() || x < 0)
{
return ans;
}
Node * curr = root;
for (int i = 0; i < size(); i++)
{
if (i == x)
{
ans = curr->value;
break;
}
curr = curr->next;
}
return ans;
}
int count(T base)
{
int num = 0;
Node * curr = root;
while (curr)
{
if (curr->value == base)
{
num++;
}
curr = curr->next;
}
return num;
}
bool remove(T base)
{
Node * curr = root;
Node * prev = NULL;
if (root->value == base)
{
delete this->root;
root = root->next;
return true;
}
while (curr)
{
if (curr->value == base)
{
Node * temp = new Node;
if (curr->next)
{
T val = curr->next->value;
temp->value = val;
temp->next = curr->next->next;
}
delete curr;
delete curr->next;
prev->next = temp;
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
void uniquify()
{
Node * curr = root;
Node * next = root->next;
while (curr)
{
while (next && curr->value == next->value)
{
Node * temp = new Node;
if (next->next)
{
T val = next->next->value;
temp->value = val;
temp->next = next->next->next;
delete next;
delete next->next;
curr->next = temp;
next = curr->next;
}
else
{
delete temp;
delete temp->next;
curr->next = NULL;
delete next;
delete next->next;
break;
}
}
curr = curr->next;
if (curr)
next = curr->next;
}
}
OListIterator<T> begin()
{
OListIterator<T> it;
it.setValue(root->value, root->next->value);
return it;
}
OListIterator<T> end()
{
Node * curr = root;
for (int i = 0; i < size(); i++)
{
curr = curr->next;
}
OListIterator<T> it;
it.setValue(curr->value);
return it;
}
};
#endif
I want to OListIterator to have access to the "Node" struct within the list class.
For this, you need to forward-declare the iterator class:
template<typename T> OListIterator;
template <typename T>
class list
{
friend class OListIterator<T>;
//... the rest
}
Alternatively, you can use a template friend declaration, but then any OListIterator type has access to any list type:
template <typename T>
class list
{
template<typename U> friend class OListIterator;
//... the rest
}
Here is a more verbose but unrelated-to-your-code example:
template<typename T> struct Iterator;
template<typename T>
struct List
{
friend struct Iterator<T>;
List(T i) : somePrivateMember(i) {}
private:
T somePrivateMember;
};
template<typename T>
struct Iterator
{
Iterator(List<T> const& list) {std::cout<<list.somePrivateMember<<std::endl;}
};
int main()
{
List<int> list(1);
Iterator<int> iterator(list);
}
The constructor of the Iterator class prints the private member somePrivateMember, whose value is 1.

Something wrong when deleting an element in a Binary search tree

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.