Helpt with error C2259: cannot instantiate abstract class - c++

I am trying to write this program for homework, and it wasn't throwing the C2259 error until I added the createList function.
I can't figure out where this problem is originating from. I am fairly new at c++ so this might be an easy fix, but I am completely lost.
Here is my main function:
#include <iostream>
#include "binarySearchTree.h"
#include "orderedLinkedList.h"
using namespace std;
int main()
{
bSearchTreeType<int> treeRoot; //error C2259: 'bSearchTreeType<int>'
//cannot instantiate abstract class
orderedLinkedList<int> newList;
int num;
cout << "Enter numbers ending with -999" << endl;
cin >> num;
while (num != -999)
{
treeRoot.insert(num);
cin >> num;
}
cout << endl << "Tree nodes in inorder: ";
treeRoot.inorderTraversal();
cout << endl;
cout << "Tree Height: " << treeRoot.treeHeight()
<< endl;
treeRoot.createList(newList);
cout << "newList: ";
newList.print();
cout << endl;
system("pause");
return 0;
}
Here is binarySearchTree.h:
//Header File Binary Search Tree
#ifndef H_binarySearchTree
#define H_binarySearchTree
#include <iostream>
#include"binaryTree.h"
using namespace std;
template<class elemType>
class bSearchTreeType : public binaryTreeType < elemType >
{
public:
//function to determine if searchItem is in search tree
bool search(const elemType& searchItem) const;
void insert(const elemType& insertItem);
void deleteNode(const elemType& deleteItem);
//update: void createList(const elemType& createItem);
virtual void createList(const elemType& newList) = 0;
private:
void deleteFromTree(nodeType<elemType> *&p);
};
template<class elemType>
void bSearchTreeType<elemType>::createList(const elemType& createItem)
{
nodeType<elemType> *current;
nodeType<elemType> *trailCurrent;
nodeType<elemType> *newNode;
newNode = new nodeType < elemType > ;
newNode->info = createItem;
newNode->lLink = nullptr;
newNode->rLink = nullptr;
if (root == nullptr)
{
root = newNode;
}
}
template<class elemType>
bool bSearchTreeType<elemType>::search(const elemType& searchItem)const
{
nodeType<elemType> *current;
bool found = false;
if (root == NULL)
{
cout << "Cannot search an empty tree." << endl;
}
else
{
current = root;
while (current != NULL && !found)
{
if (current->info == searchItem)
{
found = true;
}
else if (current->info > searchItem)
{
current = current->lLink;
}
else
{
current = current->rLink;
}
}
}
return found;
}
template<class elemType>
void bSearchTreeType<elemType>::insert(const elemType& insertItem)
{
nodeType<elemType> *current;
nodeType<elemType> *trailCurrent;
nodeType<elemType> *newNode;
newNode = new nodeType < elemType > ;
newNode->info = insertItem;
newNode->lLink = NULL;
newNode->rLink = NULL;
if (root == NULL)
{
root = newNode;
}
else
{
current = root;
while (current != NULL)
{
trailCurrent = current;
if (current->info == insertItem)
{
cout << "The item to be inserted is already in the tree";
cout << "Duplicates are not allowed." << endl;
return;
}
else if (current->info > insertItem)
{
current = current->lLink;
}
else
{
current = current->rLink;
}
}
if (trailCurrent->info > insertItem)
{
trailCurrent->lLink = newNode;
}
else
{
trailCurrent->rLink = newNode;
}
}
}
template<class elemType>
void bSearchTreeType<elemType>::deleteNode(const elemType& deleteItem)
{
nodeType<elemType> *current;
nodeType<elemType> *trailCurrent;
bool found = false;
if (root == NULL)
{
cout << "Cannot delete from an empty tree." << endl;
}
else
{
current = root;
trailCurrent = root;
while (current != NULL && !found)
{
if (current->info == deleteItem)
{
found = true;
}
else
{
trailCurrent = current;
if (current->info > deleteItem)
{
current = current->lLink;
}
else
{
current = current->rLink;
}
}
}
if (current == NULL)
{
cout << "The item to be deleted is not in the tree." << endl;
}
else if (found)
{
if (current == root)
{
deleteFromTree(root);
}
else if (trailCurrent->info > deleteItem)
{
deleteFromTree(trailCurrent->lLink);
}
else
{
deleteFromTree(trailCurrent->rLink);
}
}
else
{
cout << "The item to be deleted is not in the tree." << endl;
}
}
}
template<class elemType>
void bSearchTreeType<elemType>::deleteFromTree(nodeType<elemType>* &p)
{
nodeType<elemType> *current;
nodeType<elemType> *trailCurrent;
nodeType<elemType> *temp;
if (p == NULL)
{
cout << "Error: The node to be deleted is NULL." << endl;
}
else if (p->lLink == NULL && p->rLink == NULL)
{
temp = p;
p = NULL;
delete temp;
}
else if (p->lLink == NULL)
{
temp = p;
p = temp->rLink;
delete temp;
}
else if (p->rLink == NULL)
{
temp = p;
p = temp->lLink;
delete temp;
}
else
{
current = p->lLink;
trailCurrent = NULL;
while (current->rLink != NULL)
{
trailCurrent = current;
current = current->rLink;
}
p->info = current->info;
if (trailCurrent == NULL)
{
p->lLink = current->lLink;
}
else
{
trailCurrent->rLink = current->lLink;
}
delete current;
}
}
#endif
Also, I am 112% sure my createList function is very wrong and will not create a tree of random numbers, so I could use a little help on that as well.
Update: binaryTree.h definition
#ifndef H_binaryTree
#define H_binaryTree
#include<iostream>
using namespace std;
//Define the node
template<class elemType>
struct nodeType
{
elemType info;
nodeType<elemType> *lLink;
nodeType<elemType> *rLink;
};
template<class elemType>
class binaryTreeType
{
public:
const binaryTreeType<elemType>& operator=(const binaryTreeType<elemType>&);
bool isEmpty() const;
void inorderTraversal() const;
void preorderTraversal() const;
void postorderTraversal() const;
int treeHeight() const;
int treeNodeCount() const;
int treeLeavesCount() const;
void destroyTree();
virtual bool search(const elemType& searchItem) const = 0;
virtual void insert(const elemType& insertItem) = 0;
virtual void deleteNode(const elemType& deleteItem) = 0;
virtual void createList(const elemType& createItem) = 0;
binaryTreeType(const binaryTreeType<elemType>& otherTree);
binaryTreeType();
~binaryTreeType();
protected:
nodeType<elemType> *root;
private:
void copyTree(nodeType<elemType>*& copiedTreeRoot, nodeType<elemType>* otherTreeRoot);
void destroy(nodeType<elemType>* &p);
void inorder(nodeType<elemType> *p)const;
void preorder(nodeType<elemType> *p)const;
void postorder(nodeType<elemType> *p) const;
int height(nodeType<elemType> *p)const;
int max(int x, int y) const;
int nodeCount(nodeType<elemType> *p)const;
int leavesCount(nodeType<elemType> *p)const;
};
template <class elemType>
binaryTreeType<elemType>::binaryTreeType()
{
root = NULL;
}
template <class elemType>
bool binaryTreeType<elemType>::isEmpty() const
{
return (root == NULL);
}
template <class elemType>
void binaryTreeType<elemType>::inorderTraversal() const
{
inorder(root);
}
template <class elemType>
void binaryTreeType<elemType>::preorderTraversal() const
{
preorder(root);
}
template <class elemType>
void binaryTreeType<elemType>::postorderTraversal() const
{
postorder(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeHeight() const
{
return height(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeNodeCount() const
{
return nodeCount(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeLeavesCount() const
{
return leavesCount(root);
}
template <class elemType>
void binaryTreeType<elemType>::copyTree(nodeType<elemType>* &copiedTreeRoot,
nodeType<elemType>* otherTreeRoot)
{
if (otherTreeRoot == NULL)
copiedTreeRoot = NULL;
else
{
copiedTreeRoot = new nodeType<elemType>;
copiedTreeRoot->info = otherTreeRoot->info;
copyTree(copiedTreeRoot->lLink, otherTreeRoot->lLink);
copyTree(copiedTreeRoot->rLink, otherTreeRoot->rLink);
}
}
template <class elemType>
void binaryTreeType<elemType>::inorder(nodeType<elemType> *p) const
{
if (p != NULL)
{
inorder(p->lLink);
cout << p->info << " ";
inorder(p->rLink);
}
}
template <class elemType>
void binaryTreeType<elemType>::preorder(nodeType<elemType> *p) const
{
if (p != NULL)
{
cout << p->info << " ";
preorder(p->lLink);
preorder(p->rLink);
}
}
template <class elemType>
void binaryTreeType<elemType>::postorder(nodeType<elemType> *p) const
{
if (p != NULL)
{
postorder(p->lLink);
postorder(p->rLink);
cout << p->info << " ";
}
}
//Overload the assignment operator
template <class elemType>
const binaryTreeType<elemType>& binaryTreeType<elemType>::operator=(const binaryTreeType<elemType>& otherTree)
{
if (this != &otherTree) //avoid self-copy
{
if (root != NULL) //if the binary tree is not empty,
//destroy the binary tree
destroy(root);
if (otherTree.root == NULL) //otherTree is empty
root = NULL;
else
copyTree(root, otherTree.root);
}//end else
return *this;
}
template <class elemType>
void binaryTreeType<elemType>::destroy(nodeType<elemType>* &p)
{
if (p != NULL)
{
destroy(p->lLink);
destroy(p->rLink);
delete p;
p = NULL;
}
}
template <class elemType>
void binaryTreeType<elemType>::destroyTree()
{
destroy(root);
}
//copy constructor
template <class elemType>
binaryTreeType<elemType>::binaryTreeType
(const binaryTreeType<elemType>& otherTree)
{
if (otherTree.root == NULL) //otherTree is empty
root = NULL;
else
copyTree(root, otherTree.root);
}
//Destructor
template <class elemType>
binaryTreeType<elemType>::~binaryTreeType()
{
destroy(root);
}
template<class elemType>
int binaryTreeType<elemType>::height
(nodeType<elemType> *p) const
{
if (p == NULL)
return 0;
else
return 1 + max(height(p->lLink), height(p->rLink));
}
template <class elemType>
int binaryTreeType<elemType>::max(int x, int y) const
{
if (x >= y)
return x;
else
return y;
}
template <class elemType>
int binaryTreeType<elemType>::nodeCount(nodeType<elemType> *p) const
{
return nodeCount(root);
}
template <class elemType>
int binaryTreeType<elemType>::leavesCount(nodeType<elemType> *p) const
{
return leavesCount(root);
}
#endif

virtual void createList(const elemType& newList) = 0 ;
/// ~~~~ shouldn't be used in derived class
The pure virtual function should only be present in your abstract class which I assume is binaryTreeType

You have to override createList method since it's a virtual.

Related

Rooted binary search tree. Keeping a link to its parent

I'm trying to create a binary search tree by keeping the path: each node has a link to its parent. Below is the classic binary search. How do I change it to be able to solve my problem?
I tried adding the "father" pointer to the struct but I have no problems understanding how and when to save it. I am new to this language so be patient. thank you so much
#include <iostream>
template <class T>
class BinaryTree
{
struct node {
T value;
struct node* right;
struct node* left;
};
public:
BinaryTree();
~BinaryTree();
void add(T val);
void printPreOrder();
void printInOrder();
void printPostOrder();
int size();
bool lookup(T val);
private:
struct node* root;
int treeSize;
void add(struct node** node, T val);
bool lookup(struct node* node, T val);
void printPreOrder(struct node* node);
void printInOrder(struct node* node);
void printPostOrder(struct node* node);
void deleteTree(struct node* node);
};
template <class T>
BinaryTree<T>::BinaryTree() {
this->root = NULL;
this->treeSize = 0;
}
template <class T>
BinaryTree<T>::~BinaryTree() {
deleteTree(this->root);
}
template <class T>
int BinaryTree<T>::size() {
return this->treeSize;
}
template <class T>
void BinaryTree<T>::add(T val) {
add(&(this->root), val);
}
template <class T>
void BinaryTree<T>::add(struct node** node, T val) {
if (*node == NULL) {
struct node* tmp = new struct node;
tmp->value = val;
tmp->left = NULL;
tmp->right = NULL;
*node = tmp;
this->treeSize++;
}
else {
if (val > (*node)->value) {
add(&(*node)->right, val);
}
else {
add(&(*node)->left, val);
}
}
}
template <class T>
void BinaryTree<T>::printInOrder() {
printInOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printInOrder(struct node* node) {
if (node != NULL) {
printInOrder(node->left);
std::cout << node->value << ", ";
printInOrder(node->right);
}
}
template <class T>
void BinaryTree<T>::printPreOrder() {
printPreOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printPreOrder(struct node* node) {
if (node != NULL) {
std::cout << node->value << ", ";
printInOrder(node->left);
printInOrder(node->right);
}
}
template <class T>
void BinaryTree<T>::printPostOrder() {
printPostOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printPostOrder(struct node* node) {
if (node != NULL) {
printInOrder(node->left);
printInOrder(node->right);
std::cout << node->value << ", ";
}
}
template <class T>
void BinaryTree<T>::deleteTree(struct node* node) {
if (node != NULL) {
deleteTree(node->left);
deleteTree(node->right);
delete node;
}
}
template <class T>
bool BinaryTree<T>::lookup(T val) {
return lookup(this->root, val);
}
template <class T>
bool BinaryTree<T>::lookup(struct node* node, T val) {
if (node == NULL) {
return false;
}
else {
if (val == node->value) {
return true;
}
if (val > node->value) {
return lookup(node->right, val);
}
else {
return lookup(node->left, val);
}
}
}
I will give you the recursive solution since it is the natural way to implement it:
First it would be a good idea to define a constructor in your struct like so:
node(T value, node* left = nullptr, node* right = nullptr){
this->value = value;
this->left = left;
this->right = right;
}
Take out the struct in the struct node* root.
void insert(T value){
Node* temp = root;
insert(value, root);
}
//helper function
void insert(T value, Node* root){
if(root->left == nullptr && root->right == nullptr){
if(root->value < value){
root->left = new Node(value);
}
else{
root->right = new Node(value);
}
return;
}
if(value < root->value)insert(value, root->left);
else{
insert(value, root->right);
}
}
Not sure where you got your code it does not look correct....
I don't understand the need for pointer to pointer to struct node in your code. Pointer to struct node would suffice. As far as your question goes, you can pass the parent of current node as a third parameter in the method add. Initially it will be null. Now incase you have to go down to the child of the current node, then the current node becomes it's parent. When you have to allocate memory for value val, set the it's parent there.
template <class T>
void BinaryTree<T>::add(struct node** node, T val, struct node* parent = nullptr) {
if (*node == NULL) {
struct node* tmp = new struct node;
tmp->value = val;
tmp->left = NULL;
tmp->right = NULL;
temp->parent = parent;
*node = tmp;
this->treeSize++;
}
else {
if (val > (*node)->value) {
add(&(*node)->right, val, *node);
}
else {
add(&(*node)->left, val, *node;
}
}
}

Binary search tree not loading insert values into tree

My problem is trying to get functions treeLeavesCount() and treeNodeCount() to return a value of leaves and nodes in the tree but, my issue is after providing values through a while loop using an insert() function, the tree seems to stay empty and I know this by using an isEmpty() function before and after inserting values into the tree.
main.cpp
#include <iostream>
#include "binaryTreeType.h"
#include "bSearchTreeType.h"
using namespace std;
int main()
{
int num;
bSearchTreeType<int> *myTree= new bSearchTreeType<int>();
//test if tree is empty
if(myTree->isEmpty())
cout << "yes" << endl;
else
cout << "no" << endl;
cout << "Line 10: Enter numbers ending with -999"<< endl;
cin >> num;
while (num != -999)
{
myTree->insert(num);
cin >> num;
}
myTree->inorderTraversal();
int p;
p=myTree->treeNodeCount();
cout << p << endl;
p=myTree->treeLeavesCount();
cout << p << endl;
//test if tree is empty after data is inserted
if(myTree->isEmpty())
cout << "yes" << endl;
else
cout << "no" << endl;
delete myTree;
return 0;
}
binaryTreeType.h
#ifndef BINARYTREETYPE_H
#define BINARYTREETYPE_H
#include <queue>
template <class elemType>
struct binaryTreeNode
{
elemType info;
binaryTreeNode<elemType> *llink;
binaryTreeNode<elemType> *rlink;
};
template <class elemType>
class binaryTreeType
{
public:
const binaryTreeType<elemType>& operator=(const binaryTreeType<elemType>&);
//Overload the assignment operator.
bool isEmpty() const;
//Returns true if the binary tree is empty;
//otherwise, returns false.
void inorderTraversal() const;
//Function to do an inorder traversal of the binary tree.
void preorderTraversal() const;
//Function to do a preorder traversal of the binary tree.
void postorderTraversal() const;
//Function to do a postorder traversal of the binary tree.
int treeHeight() const;
//Returns the height of the binary tree.
int treeNodeCount() const;
//Returns the number of nodes in the binary tree.
int treeLeavesCount() const;
//Returns the number of leaves in the binary tree.
void destroyTree();
//Deallocates the memory space occupied by the binary tree.
//Postcondition: root = NULL;
binaryTreeType(const binaryTreeType<elemType>& otherTree);
//copy constructor
binaryTreeType();
//default constructor
~binaryTreeType();
//destructor
protected:
binaryTreeNode<elemType> *root;
private:
void copyTree(binaryTreeNode<elemType>* &copiedTreeRoot,binaryTreeNode<elemType>* otherTreeRoot);
//Makes a copy of the binary tree to which
//otherTreeRoot points. The pointer copiedTreeRoot
//points to the root of the copied binary tree.
void destroy(binaryTreeNode<elemType>* &p);
//Function to destroy the binary tree to which p points.
//Postcondition: p = NULL
void inorder(binaryTreeNode<elemType> *p) const;
//Function to do an inorder traversal of the binary
//tree to which p points.
void preorder(binaryTreeNode<elemType> *p) const;
//Function to do a preorder traversal of the binary
//tree to which p points.
void postorder(binaryTreeNode<elemType> *p) const;
//Function to do a postorder traversal of the binary
//tree to which p points.
int height(binaryTreeNode<elemType> *p) const;
//Function to return the height of the binary tree
//to which p points.
int max(int x, int y) const;
//Returns the larger of x and y.
int nodeCount(binaryTreeNode<elemType> *p) const;
//Function to return the number of nodes in the binary
//tree to which p points
int leavesCount(binaryTreeNode<elemType> *p) const;
//Function to return the number of leaves in the binary
//tree to which p points
};
template <class elemType>
bool binaryTreeType<elemType>::isEmpty() const
{
return (root == NULL);
};
template <class elemType>
binaryTreeType<elemType>::binaryTreeType()
{
root = NULL;
}
template <class elemType>
void binaryTreeType<elemType>::inorderTraversal() const
{
inorder(root);
}
template <class elemType>
void binaryTreeType<elemType>::preorderTraversal() const
{
preorder(root);
}
template <class elemType>
void binaryTreeType<elemType>::postorderTraversal() const
{
postorder(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeHeight() const
{
return height(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeNodeCount() const
{
return nodeCount(root);
}
template <class elemType>
int binaryTreeType<elemType>::treeLeavesCount() const
{
return leavesCount(root);
}
template <class elemType>
void binaryTreeType<elemType>::inorder(binaryTreeNode<elemType> *p) const
{
if (p != NULL)
{
inorder(p->llink);
std::cout << p->info << " ";
inorder(p->rlink);
}
}
template <class elemType>
void binaryTreeType<elemType>::preorder(binaryTreeNode<elemType> *p) const
{
if (p != NULL)
{
std::cout << p->info << " ";
preorder(p->llink);
preorder(p->rlink);
}
}
template <class elemType>
void binaryTreeType<elemType>::postorder(binaryTreeNode<elemType> *p) const
{
if (p != NULL)
{
postorder(p->llink);
postorder(p->rlink);
std::cout << p->info << " ";
}
}
template <class elemType>
int binaryTreeType<elemType>::height(binaryTreeNode<elemType> *p) const
{
if (p == NULL)
return 0;
else
return 1 + max(height(p->llink), height(p->rlink));
}
template <class elemType>
int binaryTreeType<elemType>::max(int x, int y) const
{
if (x >= y)
return x;
else
return y;
}
template <class elemType>
void binaryTreeType<elemType>::copyTree(binaryTreeNode<elemType>* &copiedTreeRoot,binaryTreeNode<elemType>* otherTreeRoot)
{
if (otherTreeRoot == NULL)
copiedTreeRoot = NULL;
else
{
copiedTreeRoot = new binaryTreeNode<elemType>;
copiedTreeRoot->info = otherTreeRoot->info;
copyTree(copiedTreeRoot->llink, otherTreeRoot->llink);
copyTree(copiedTreeRoot->rlink, otherTreeRoot->rlink);
}
} //end copyTree
template <class elemType>
void binaryTreeType<elemType>::destroy(binaryTreeNode<elemType>* &p)
{
if (p != NULL)
{
destroy(p->llink);
destroy(p->rlink);
delete p;
p = NULL;
}
}
template <class elemType>
void binaryTreeType<elemType>::destroyTree()
{
destroy(root);
}
template <class elemType>
binaryTreeType<elemType>::binaryTreeType(const binaryTreeType<elemType>& otherTree)
{
if (otherTree.root == NULL) //otherTree is empty
root = NULL;
else
copyTree(root, otherTree.root);
}
template <class elemType>
binaryTreeType<elemType>::~binaryTreeType()
{
destroy(root);
}
template <class elemType>
const binaryTreeType<elemType>& binaryTreeType<elemType>::operator=(const binaryTreeType<elemType>& otherTree)
{
if (this != &otherTree) //avoid self-copy
{
if (root != NULL) //if the binary tree is not empty,
//destroy the binary tree
destroy(root);
if (otherTree.root == NULL) //otherTree is empty
root = NULL;
else
copyTree(root, otherTree.root);
}//end else
return *this;
}
template <class elemType>
int binaryTreeType<elemType>::leavesCount(binaryTreeNode<elemType> *p) const
{
if(p == NULL)
return 0;
if(p->llink == NULL && p->rlink==NULL)
return 1;
else
return leavesCount(p->llink) + leavesCount(p->rlink);
}
template <class elemType>
int binaryTreeType<elemType> ::nodeCount(binaryTreeNode<elemType> *p) const
{
int count = 1;
if ( p == NULL ){
return 0;
}else{
count += nodeCount(p->llink);
count += nodeCount(p->rlink);
}
return count;
}
#endif // BINARYTREETYPE_H
bSearchTreeType.h
#ifndef BSEARCHTREETYPE_H
#define BSEARCHTREETYPE_H
#include "binaryTreeType.h"
#include <iostream>
#include <cassert>
template <class elemType>
class bSearchTreeType : public binaryTreeType<elemType>
{
public:
bool search(const elemType& searchItem) const;
//Function to determine if searchItem is in the binary
//search tree.
//Postcondition: Returns true if searchItem is found in the
// binary search tree; otherwise, returns false.
void insert(const elemType& insertItem);
//Function to insert insertItem in the binary search tree.
//Postcondition: If no node in the binary search tree has the
// same info as insertItem, a node with the info insertItem
// is created and inserted in the binary search tree.
void deleteNode(const elemType& deleteItem);
//Function to delete deleteItem from the binary search tree.
//Postcondition: If a node with the same info as deleteItem
// is found, it is deleted from the binary search tree.
protected:
binaryTreeNode<elemType> *root;
private:
void deleteFromTree(binaryTreeNode<elemType>* &p);
//Function to delete the node to which p points is deleted
//from the binary search tree.
//Postcondition: The node to which p points is deleted from
// the binary search tree.
};
using namespace std;
template <class elemType>
bool bSearchTreeType<elemType>::search(const elemType& searchItem) const
{
binaryTreeNode<elemType> *current;
bool found = false;
if (root == NULL)
cerr << "Cannot search the empty tree." << endl;
else
{
current = root;
while (current != NULL && !found)
{
if (current->info == searchItem)
found = true;
else if (current->info > searchItem)
current = current->llink;
else
current = current->rlink;
}//end while
}//end else
return found;
}//end search
template <class elemType>
void bSearchTreeType<elemType>::insert(const elemType& insertItem)
{
binaryTreeNode<elemType> *current; //pointer to traverse the tree
binaryTreeNode<elemType> *trailCurrent; //pointer behind current
binaryTreeNode<elemType> *newNode; //pointer to create the node
newNode = new binaryTreeNode<elemType>;
assert(newNode != NULL);
newNode->info = insertItem;
newNode->llink = NULL;
newNode->rlink = NULL;
if (root == NULL)
root = newNode;
else
{
current = root;
while (current != NULL)
{
trailCurrent = current;
if (current->info == insertItem)
{
std::cerr << "The insert item is already in the list-";
std::cerr << "duplicates are not allowed." << insertItem << std::endl;
return;
}
else if (current->info > insertItem)
current = current->llink;
else
current = current->rlink;
}//end while
if (trailCurrent->info > insertItem)
trailCurrent->llink = newNode;
else
trailCurrent->rlink = newNode;
}
}//end insert
template <class elemType>
void bSearchTreeType<elemType>::deleteFromTree(binaryTreeNode<elemType>* &p)
{
binaryTreeNode<elemType> *current;//pointer to traverse the tree
binaryTreeNode<elemType> *trailCurrent; //pointer behind current
binaryTreeNode<elemType> *temp; //pointer to delete the node
if (p == NULL)
cerr << "Error: The node to be deleted is NULL." << endl;
else if(p->llink == NULL && p->rlink == NULL)
{
temp = p;
p = NULL;
delete temp;
}
else if(p->llink == NULL)
{
temp = p;
p = temp->rlink;
delete temp;
}
else if(p->rlink == NULL)
{
temp = p;
p = temp->llink;
delete temp;
}
else
{
current = p->llink;
trailCurrent = NULL;
while (current->rlink != NULL)
{
trailCurrent = current;
current = current->rlink;
}//end while
p->info = current->info;
if (trailCurrent == NULL) //current did not move;
//current == p->llink; adjust p
p->llink = current->llink;
else
trailCurrent->rlink = current->llink;
delete current;
}//end else
}//end deleteFromTree
template <class elemType>
void bSearchTreeType<elemType>::deleteNode(const elemType& deleteItem)
{
binaryTreeNode<elemType> *current; //pointer to traverse the tree
binaryTreeNode<elemType> *trailCurrent; //pointer behind current
bool found = false;
if (root == NULL)
std::cout << "Cannot delete from the empty tree." << endl;
else
{
current = root;
trailCurrent = root;
while (current != NULL && !found)
{
if (current->info == deleteItem)
found = true;
else
{
trailCurrent = current;
if (current->info > deleteItem)
current = current->llink;
else
current = current->rlink;
}
}//end while
if (current == NULL)
std::cout << "The delete item is not in the tree." << endl;
else if (found)
{
if (current == root)
deleteFromTree(root);
else if (trailCurrent->info > deleteItem)
deleteFromTree(trailCurrent->llink);
else
deleteFromTree(trailCurrent->rlink);
}//end if
}
}//end deleteNode
#endif // BSEARCHTREETYPE_H
(That's a humongous amount of code. Please remove everything your test case doesn't need next time.)
Cutting your code down to the bare essentials, we get
template <class elemType>
class binaryTreeType
{
public:
bool isEmpty() const;
protected:
binaryTreeNode<elemType> *root;
};
template <class elemType>
bool binaryTreeType<elemType>::isEmpty() const
{
return (root == NULL);
};
template <class elemType>
class bSearchTreeType : public binaryTreeType<elemType>
{
void insert(const elemType& insertItem);
protected:
binaryTreeNode<elemType> *root;
};
template <class elemType>
void bSearchTreeType<elemType>::insert(const elemType& insertItem)
{
// ...
if (root == NULL)
root = newNode;
else
{
current = root;
//...
}
}//end insert
And now we can see that you declare two member variables called "root".
The one in bSearchTreeType hides the one in binaryTreeType - it's not a redeclaration or "override" of the same variable.
This means that your binaryTreeType member functions (such as isEmpty) use the root in binaryTreeType, while the member functions of bSearchTreeType (such as insert) use the root in bSearchTreeType, so after insert has updated one of the roots the other one is still null.
Incidentally, this issue is also difficult to discover with a debugger, where you'll just be staring at a variable whose value changes as if by magic.
You need to do two things:
Remove the root member from bSearchTreeType
Because these are templates, you also need to change root to this->root in the bSearchTreeType member functions. (Finding out why left as an exercise - it's an essay of its own.)
(It seems to work with just these changes, by the way. Well done.)

Outputing number of leaf nodes in a Binary Search Tree

Im trying to figure out how to calculate the number of leaf nodes in a binary search tree.
I keep getting a run-time error and CodeBlocks keeps crashing at the final return statement. I've seen multiple examples on here and I still can't seem to understand where I'm going wrong.
I'm trying to do this recursively however as i stated previously as soon as i add the function number_of_leaves(p -> left)+ number_of_leaves(p-> right)
CodeBlocks stops working after it prints out:
Empty tree has 0 leaf nodes. Answer:0
Single node has 1 leaf node. Answer 1
Crashes here
.
#include <queue>
#include <stack>
#include <iostream>
#include <vector>
#include <stdlib.h>
#ifndef BINARY_SEARCH_TREE
#define BINARY_SEARCH_TREE
template<class T>
class Stack: public std::stack<T> {
public:
T pop() { T tmp = std::stack<T>::top(); std::stack<T>::pop(); return tmp; }
};
template<class T>
class Queue: public std::queue<T> {
public:
T dequeue() { T tmp = std::queue<T>::front(); std::queue<T>::pop(); return tmp; }
void enqueue(const T& el) { push(el); }
};
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 is_empty() const { return root == 0; }
void preorder() { preorder(root); }
void inorder() { inorder(root); }
void postorder() { postorder(root); }
void insert(const T&);
T* search(const T& el) const { return search(root, el); }
void find_and_delete_by_copying(const T&);
void find_and_delete_by_merging(const T&);
void breadth_first();
void balance(std::vector<T>, int, int);
bool is_perfectly_balanced() const { return is_perfectly_balanced(root) >= 0; }
int number_of_leaves() const { return number_of_leaves(root); }
T* recursive_search(const T& el) const { return recursive_search(root, el); }
void recursive_insert(const T& el) { recursive_insert(root, el); }
protected:
void clear(BSTNode<T>*);
T* search(BSTNode<T>*, const T&) const;
void preorder(BSTNode<T>*);
void inorder(BSTNode<T>*);
void postorder(BSTNode<T>*);
virtual void visit(BSTNode<T>* p) // virtual allows re-definition in derived classes
{ std::cout << p->el << " "; }
void delete_by_copying(BSTNode<T>*&);
void delete_by_merging(BSTNode<T>*&);
int is_perfectly_balanced(BSTNode<T>*) const; // To be provided (A4)
int number_of_leaves(BSTNode<T>*) const; // To be provided (A4)
void recursive_insert(BSTNode<T>*&, const T&); // To be provided (P6)
T* recursive_search(BSTNode<T>*, const T&) const; // To be provided (P6)
BSTNode<T>* root;
};
#endif
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>
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>
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>::delete_by_copying(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.
}
// find_and_delete_by_copying() searches the tree to locate the node containing
// el. If the node is located, the function delete_by_copying() is called.
template<class T>
void BST<T>::find_and_delete_by_copying(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)
delete_by_copying(root);
else if (prev->left == p)
delete_by_copying(prev->left);
else
delete_by_copying(prev->right);
}
else if (root != 0)
std::cout << "el " << el << " is not in the tree" << std::endl;
else
std::cout << "the tree is empty" << std::endl;
}
template<class T>
void BST<T>::delete_by_merging(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>::find_and_delete_by_merging(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)
delete_by_merging(root);
else if (prev->left == node)
delete_by_merging(prev->left);
else
delete_by_merging(prev->right);
}
else if (root != 0)
std::cout << "el " << el << " is not in the tree" << std::endl;
else
std::cout << "the tree is empty" << std::endl;
}
template<class T>
void BST<T>::breadth_first()
{
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>::balance (std::vector<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);
}
}
template<class T>
void BST<T>::recursive_insert(BSTNode<T>*& p, const T& el)
{
if (p == 0) // Anchor case, tail recursion
p = new BSTNode<T>(el);
else if (el < p->el)
recursive_insert(p->left, el);
else
recursive_insert(p->right, el);
}
template<class T>
T* BST<T>::recursive_search(BSTNode<T>* p, const T& el) const
{
if (p != 0) {
if (el == p->el) // Anchor case, tail recursion
return &p->el;
else if (el < p->el)
return recursive_search(p->left, el);
else
return recursive_search(p->right, el);
}
else
return 0;
}
Problem is here***
I've tryed having a seperate counter to count the nodes, but it just prints all 0s. As soon as i add in the number_of_leaves() it crashes
template<class T>
int BST<T>::number_of_leaves(BSTNode<T>*) const {
BSTNode<T> *p = root;
if(p == NULL){
return 0;
}
if(p->left == NULL && p->right==NULL){
return 1;
}
else
return number_of_leaves(p->left) + number_of_leaves(p-> right);
}
Testing file below:
#include "BST.h"
#include <iostream>
using namespace std;
int main()
{
BST<int> a;
cout << "Empty tree has 0 leaf nodes. Answer: " << a.number_of_leaves() << endl;
a.insert(4);
cout << "Single node has 1 leaf node. Answer: " << a.number_of_leaves() << endl;
a.insert(2);
cout << "Linked list of 2 nodes has 1 leaf node. Answer: "
<< a.number_of_leaves() << endl;
a.insert(6);
cout << "Full binary tree of 3 nodes has 2 leaf nodes. Answer: "
<< a.number_of_leaves() << endl;
a.insert(3), a.insert(1), a.insert(5), a.insert(7);
cout << "Full binary tree of 7 nodes has 4 leaf nodes. Answer: "
<< a.number_of_leaves() << endl;
return 0;
}
In number_of_leaves(BSTNode<T>*), you discard the passed argument and always start from root. You then go down recursively and always do precisely the same operations, which leads to StackOverflow (sorry, I couldn't resist :p). You reach the maximum number of function calls and program is terminated.
template<class T>
int BST<T>::number_of_leaves(BSTNode<T>* start) const
{
if(start == NULL)
{
return 0;
}
if(start->left == NULL && start->right==NULL)
{
return 1;
}
return number_of_leaves(start->left) + number_of_leaves(start-> right);
}

How to correctly use a nested class of a template class?

all!
I am trying to implement a simple template class binary search tree.
I run into a couple problem with the definitions of functions.
The following is my BST class code
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
#include <iostream>
#include <stdlib.h>
using namespace std;
template<class T>
class BST
{
struct TreeNode {
TreeNode* left;
TreeNode* right;
T value;
};
//member functions
void destroyTree(TreeNode* leaf);
void insert(T key, TreeNode* leaf);
TreeNode* search(T key, TreeNode* leaf);
void printInOrder(TreeNode* leaf);
void printPreOrder(TreeNode* leaf);
void printPostOrder(TreeNode* leaf);
//memebr variables
TreeNode* root;
public:
enum Traversal { INORDER, PREORDER, POSTORDER };
BST();
BST(T key);
~BST();
void insert(T key);
TreeNode* search(T key);
void printTree(T option);
void destroyTree();
};
template <class T>
BST<T>::BST()
{
root = NULL;
};
template <class T>
BST<T>::BST(T key)
{
root = new TreeNode;
root->left = NULL;
root->right = NULL;
root->value = key;
};
template <class T>
BST<T>::~BST()
{
destroyTree();
};
template <class T>
void BST<T>::destroyTree(TreeNode* leaf)
{
if (leaf->left != NULL) destroyTree(leaf->left);
if (leaf->right != NULL) destroyTree(leaf->right);
delete leaf;
leaf = nullptr;
};
template <class T>
void insert(T key, BST<T>::TreeNode* leaf)
{
if (leaf->value == key)
{
cout << "failed inserting node: duplicate item" << endl;
return;
}
else if (leaf->value < key)
{
if (leaf->right != NULL) insert(key, leaf->right);
else
{
TreeNode newNode = new TreeNode;
newNode->left = NULL;
newNode->right = NULL;
newNode->value = key;
leaf->right = newNode;
}
}
else
{
if (leaf->left != NULL) insert(key, leaf->left);
else
{
TreeNode newNode = new TreeNode;
newNode->left = NULL;
newNode->right = NULL;
newNode->value = key;
leaf->left = newNode;
}
}
};
template <class T>
BST<T>::TreeNode* BST<T>::search(T key, TreeNode* leaf)
{
if (leaf == NULL) return NULL;
if (leaf->value == key) return leaf;
else if (leaf->vluae < key) return search(key, leaf->right);
else return search(key, leaf->left);
};
template <class T>
void printInOrder(TreeNode* leaf)
{
if (leaf->left != NULL) printInOrder(leaf->left);
cout << leaf->value << " ";
if (leaf->right != NULL) printInOrder(leaf->right);
};
template <class T>
void printPreOrder(TreeNode* leaf)
{
cout << leaf->value << " ";
if (leaf->left != NULL) printPreOrder(leaf->left);
if (leaf->right != NULL) printPreOrder(leaf->right);
};
template <class T>
void printPostOrder(TreeNode* leaf)
{
if (leaf->left != NULL) printPostOrder(leaf->left);
if (leaf->right != NULL) printPostOrder(leaf->right);
cout << leaf->value << " ";
};
template <class T>
void BST<T>::insert(int key)
{
if (this->root == NULL)
{
this->root = new TreeNode;
this->root->left = NULL;
this->root->right = NULL;
this->root->value = key;
}
else insert(key, root);
};
template <class T>
BST<T>::TreeNode* BST<T>::search(int key)
{
search(key, this->root);
};
template <class T>
void BST<T>::printTree(int option)
{
switch (option)
{
case BST<T>::INORDER:
printInOrder(this->root);
cout << endl;
break;
case BST<T>::POSTORDER:
printPostOrder(this->root);
cout << endl;
break;
case BST<T>::PREORDER:
printPreOrder(this->root);
cout << endl;
break;
}
};
template <class T>
void BST<T>::destroyTree()
{
destroyTree(this->root);
};
#endif
As you can see, for the void insert(T key, BST<T>::TreeNode* leaf) and BST<T>::TreeNode* BST<T>::search(T key, TreeNode* leaf) functions I need to do things with TreeNode class like returning an object of it or passing it to a function, which is a nested type defined in class BST.
The errors I am getting are at syntax errors, but I don't know where I am doing wrong in the code.
Any advice or suggestion would be appreciated!
You should:
replace every single TreeNode by BST<T>::TreeNode, because there could be different TreeNode definitions so the compiler need to know the one you are talking about.
add typename in front of every BST<T>::TreeNode. There could be several different definitions for BST<T>::TreeNode, even some that are not types, so you need to tell the compiler that it is a type.
#include <iostream>
#include <stdlib.h>
using namespace std;
template<class T>
class BST
{
struct TreeNode {
TreeNode* left;
TreeNode* right;
T value;
};
//member functions
void destroyTree(TreeNode* leaf);
void insert(T key, TreeNode* leaf);
TreeNode* search(T key, TreeNode* leaf);
void printInOrder(TreeNode* leaf);
void printPreOrder(TreeNode* leaf);
void printPostOrder(TreeNode* leaf);
//memebr variables
TreeNode* root;
public:
enum Traversal { INORDER, PREORDER, POSTORDER };
BST();
BST(T key);
~BST();
void insert(T key);
TreeNode* search(T key);
void printTree(T option);
void destroyTree();
};
template <class T>
BST<T>::BST()
{
root = NULL;
};
template <class T>
BST<T>::BST(T key)
{
root = new TreeNode;
root->left = NULL;
root->right = NULL;
root->value = key;
};
template <class T>
BST<T>::~BST()
{
destroyTree();
};
template <class T>
void BST<T>::destroyTree(TreeNode* leaf)
{
if (leaf->left != NULL) destroyTree(leaf->left);
if (leaf->right != NULL) destroyTree(leaf->right);
delete leaf;
leaf = nullptr;
};
template <class T>
void BST<T>::insert(T key, typename BST<T>::TreeNode* leaf)
{
if (leaf->value == key)
{
cout << "failed inserting node: duplicate item" << endl;
return;
}
else if (leaf->value < key)
{
if (leaf->right != NULL) insert(key, leaf->right);
else
{
BST<T>::TreeNode* newNode = new TreeNode;
newNode->left = NULL;
newNode->right = NULL;
newNode->value = key;
leaf->right = newNode;
}
}
else
{
if (leaf->left != NULL) insert(key, leaf->left);
else
{
BST<T>::TreeNode* newNode = new TreeNode;
newNode->left = NULL;
newNode->right = NULL;
newNode->value = key;
leaf->left = newNode;
}
}
};
template <class T>
typename BST<T>::TreeNode* BST<T>::search(T key, typename BST<T>::TreeNode* leaf)
{
if (leaf == NULL) return NULL;
if (leaf->value == key) return leaf;
else if (leaf->vluae < key) return search(key, leaf->right);
else return search(key, leaf->left);
};
template <class T>
void printInOrder(typename BST<T>::TreeNode* leaf)
{
if (leaf->left != NULL) printInOrder(leaf->left);
cout << leaf->value << " ";
if (leaf->right != NULL) printInOrder(leaf->right);
};
template <class T>
void printPreOrder(typename BST<T>::TreeNode* leaf)
{
cout << leaf->value << " ";
if (leaf->left != NULL) printPreOrder(leaf->left);
if (leaf->right != NULL) printPreOrder(leaf->right);
};
template <class T>
void printPostOrder(typename BST<T>::TreeNode* leaf)
{
if (leaf->left != NULL) printPostOrder(leaf->left);
if (leaf->right != NULL) printPostOrder(leaf->right);
cout << leaf->value << " ";
};
template <class T>
void BST<T>::insert(T key)
{
if (this->root == NULL)
{
this->root = new TreeNode;
this->root->left = NULL;
this->root->right = NULL;
this->root->value = key;
}
else insert(key, root);
};
template <class T>
typename BST<T>::TreeNode* BST<T>::search(T key)
{
search(key, this->root);
};
template <class T>
void BST<T>::printTree(T option)
{
switch (option)
{
case BST<T>::INORDER:
printInOrder(this->root);
cout << endl;
break;
case BST<T>::POSTORDER:
printPostOrder(this->root);
cout << endl;
break;
case BST<T>::PREORDER:
printPreOrder(this->root);
cout << endl;
break;
}
};
template <class T>
void BST<T>::destroyTree()
{
destroyTree(this->root);
};
Should work now, but was full of small mistakes like:
TreeNode newNode = new TreeNode;,
template <class T> void insert instead of template <class T> void BST<T>::insert

c++ access violation with classes [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hi I am getting an access violation reading error in my linked list header file. The project takes a binary tree and turns it into an ordered linked list. the binary tree header:
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
#include "dsexceptions.h"
#include "LinkedList.h"
#include <iostream>
using namespace std;
template <typename Comparable>
class BinarySearchTree
{
public:
BinarySearchTree( ) :root( NULL )
{ }
BinarySearchTree(const BinarySearchTree & rhs) : root(NULL)
{ *this = rhs; }
~BinarySearchTree( )
{ makeEmpty( ); }
const Comparable & findMin( ) const
{
if (isEmpty( ))
throw UnderflowException( );
return findMin(root)->element;
}
const Comparable & findMax( ) const
{
if(isEmpty( ))
throw UnderflowException( );
return findMax( root )->element;
}
bool contains(const Comparable & x) const
{ return contains(x, root); }
bool isEmpty( ) const
{ return root == NULL; }
void printTree(ostream & out = cout)
{
if (isEmpty( ))
out << "Empty tree" << endl;
else
printTree(root, out);
}
void makeEmpty( )
{ makeEmpty(root); }
void insert(const Comparable & x)
{ insert(x, root); }
void remove(const Comparable & x)
{ remove(x, root); }
const BinarySearchTree & operator=(const BinarySearchTree & rhs)
{
if (this != &rhs)
{
makeEmpty( );
root = clone(rhs.root);
}
return *this;
}
void toList(linkedlist l)
{ toList(l, root); }
private:
struct BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(const Comparable & theElement, BinaryNode *lt, BinaryNode *rt)
: element(theElement), left(lt), right(rt) { }
};
BinaryNode *root;
void toList(linkedlist l, BinaryNode *&t)
{
if(t==NULL)
{ return; }
toList(l,t->left);
l.add(t->element);
toList(l,t->right);
}
void printTree(BinaryNode *&t, ostream & out = cout)
{
if(t==NULL)
{ return; }
printTree(t->left,out);
cout << t->element << endl;
printTree(t->right,out);
}
void insert(const Comparable & x, BinaryNode * & t)
{
if (t == NULL)
t = new BinaryNode(x, NULL, NULL);
else if (x < t->element)
insert(x, t->left);
else if (t->element < x)
insert(x, t->right);
else; // Duplicate; do nothing
}
void remove(const Comparable & x, BinaryNode * & t)
{
if (t == NULL)
return; // Item not found; do nothing
if (x < t->element)
remove(x, t->left);
else if (t->element < x)
remove(x, t->right);
else if (t->left != NULL && t->right != NULL) // Two children
{
t->element = findMin(t->right)->element;
remove(t->element, t->right);
}
else
{
BinaryNode *oldNode = t;
t = (t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
BinaryNode * findMin(BinaryNode *t) const
{
if (t == NULL)
return NULL;
if (t->left == NULL)
return t;
return findMin(t->left);
}
BinaryNode * findMax(BinaryNode *t) const
{
if (t != NULL)
while (t->right != NULL)
t = t->right;
return t;
}
bool contains(const Comparable & x, BinaryNode *t) const
{
if (t == NULL)
return false;
else if (x < t->element)
return contains(x, t->left);
else if (t->element < x)
return contains(x, t->right);
else
return true; // Match
}
void makeEmpty(BinaryNode * & t)
{
if (t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
}
BinaryNode * clone(BinaryNode *t) const
{
if (t == NULL)
return NULL;
else
return new BinaryNode(t->element, clone(t->left), clone(t->right));
}
};
#endif
the linked list header:
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include <iostream>
using namespace std;
class linkedlist
{
private:
struct lNode{
int data;
lNode *next;
};
struct lNode *head;
public:
linkedlist()
{ struct lNode *head = new lNode;
head->next = NULL;
}
void add(int n) {
lNode *newlNode = new lNode;
newlNode->data = n;
newlNode->next = NULL;
lNode *cur = head;
while(true) {
if(cur->next == NULL)
{
cur->next = newlNode;
break;
}
cur = cur->next;
}
}
void display() {
lNode *list = head;
while(true)
{
if (list->next == NULL)
{
cout << list->data << endl;
break;
}
cout << list->data << endl;
list = list->next;
}
cout << "done" << endl;
}
};
#endif
the main cpp file:
#include <iostream>
#include "BinarySearchTree.h"
#include "LinkedList.h"
using namespace std;
int main( )
{
BinarySearchTree<int> t;
linkedlist l;
int i;
cout << "inserting nodes into tree" << endl;
t.insert(50);
t.insert(60);
t.insert(30);
t.insert(20);
t.insert(40);
t.insert(70);
t.insert(55);
t.insert(65);
t.insert(25);
t.insert(35);
t.insert(85);
t.insert(100);
t.insert(15);
t.insert(45);
t.insert(95);
t.insert(105);
t.insert(10);
t.insert(75);
t.insert(110);
t.insert(12);
t.insert(92);
t.insert(32);
t.insert(82);
t.insert(22);
t.insert(32);
t.printTree( );
t.toList(l);
cout << "Finished processing" << endl;
l.display();
return 0;
}
The location of the error is in the linked list header file here: if(cur->next == NULL). I do not see how it could be an access error as everything is contained inside that class.
In the code above you have this section of code:
struct lNode *head;
public:
linkedlist()
{ struct lNode *head = new lNode;
head->next = NULL;
}
That code is defining two instances of the head node which I'm sure is not what you want.
The ctor should be something more like this:
linkedlist()
{
head = new lNode;
head->next = NULL;
}
Your code does not test for the empty list -- that is where there are no elements in the list and the head is NULL.
Also, you are missing any constructors which is initializing the class, so it may very well be that head has an undefined value -- also there add method make not use of the loop, or make any recording of the added elements...
So in short, there are a lot of programming issues to fix.