I am trying to remove the element from linked list recursively, but the remove function is not working. I need some help in solving this.
My node.h function
#ifndef NODE_
#define NODE_
template<class ItemType>
class Node {
private:
ItemType item; // A data item
Node<ItemType>* next; // Pointer to next node
public:
Node();
Node(const ItemType& anItem);
Node(const ItemType& anItem, Node<ItemType>* nextNodePtr);
void setItem(const ItemType& anItem);
void setNext(Node<ItemType>* nextNodePtr);
ItemType getItem() const;
Node<ItemType>* getNext() const;
}; // end Node
#include "Node.cpp"
#endif
My node.cpp file:
#include "Node.h"
template<class ItemType>
Node<ItemType>::Node() : next(nullptr)
{
} // end default constructor
template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem) : item(anItem), next(nullptr)
{
} // end constructor
template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem, Node<ItemType>* nextNodePtr) :
item(anItem), next(nextNodePtr)
{
} // end constructor
template<class ItemType>
void Node<ItemType>::setItem(const ItemType& anItem)
{
item = anItem;
} // end setItem
template<class ItemType>
void Node<ItemType>::setNext(Node<ItemType>* nextNodePtr)
{
next = nextNodePtr;
} // end setNext
template<class ItemType>
ItemType Node<ItemType>::getItem() const
{
return item;
} // end getItem
template<class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const
{
return next;
} // end getNext
My main function:
#include <iostream>
#include "Node.h"
using namespace std;
// Function to insert an item into the front of a linked list
template<class T>
void insert(Node<T>* &headPtr, const T& entry)
{
// Create a new node and have the next pointer point to current front
Node<T> *newNodePtr = new Node<T>( entry , headPtr );
// Current front now becomes this new node
headPtr = newNodePtr;
}
// Recursive function to remove an item from a linked list
// Returns true if the operation was done; false, otherwise
template< typename T >
bool removes(Node<T>* &nodePtr, T target)
{
if(!nodePtr)
{
return false;
}
if(nodePtr->getNext() != NULL)
{
Node<T>*next = nodePtr->getNext();
removes(next,target);
if(nodePtr->getNext()->getItem()==target)
{
Node<T>*del = nodePtr;
nodePtr->setNext(nodePtr->getNext()->getNext());
delete del;
return true;
}
//nodePtr->setNext(nodePtr->getNext());
}
}
// Recursive function to display the contents of a linked list
// in the reverse order.
template<class T>
void display(Node<T> *currNodePtr)
{
// YOUR CODE GOES HERE - CHECK YOUR NOTES!
Node<T> *curr=currNodePtr;
if(curr!=NULL)
{
cout<<curr->getItem();
display(curr->getNext());
}
cout<<endl;
}
int main()
{
// (1) Declare an empty linked list of unsigned values
// based on the Node class and call it myList
Node<unsigned>*myList;
// (2) Read in values from standard input. Non-negative
// values are inserted into myList and a negative
// value terminates input.
int data=0;
unsigned k;
while(cin>>data)
{
if (data>=0)
{
k=data;
insert(myList,k);
}
else
{
break;
}
}
cout<<"out of loop";
// (3) Display the contents of the linked list myList
// in the order they were entered (hence, the display()
// function displays myList in reverse order!
display(myList);
// (4) Read in values from standard input. Non-negative
// values are removed from myList and a negative
// value terminates input.
int data1=0;
unsigned m;
while(cin>>data1)
{
if (data1>=0)
{
m=data1;
removes(myList,m);
}
else
{
break;
}
}
// (5) Display the contents of the linked list myList
// in the order they were entered (hence, the display()
// function displays myList in reverse order!
cout<<endl;
display(myList);
}
The remove function is in main. It is not removing the correct element. For example, in the list of 1 2 3 4 5, if I try to remove 3 it is removing 2.
Related
Trying to finish my doublely linked list program, but I don't really know how to create a node using a class. I've only ever used sctructs.
DoubleNode.h:
#ifndef DOUBLE_NODE_H_
#define DOUBLE_NODE_H_
template<class ItemType>
class DoubleNode
{
private:
ItemType item;
DoubleNode<ItemType>* prev;
DoubleNode<ItemType>* next;
public:
DoubleNode(const ItemType& anItem, DoubleNode<ItemType>* prevPtr, DoubleNode<ItemType>* nextPtr);
~DoubleNode();
ItemType getItem() const;
DoubleNode<ItemType>* getPrev() const;
DoubleNode<ItemType>* getNext() const;
void setPrev(DoubleNode<ItemType>* prevPtr);
void setNext(DoubleNode<ItemType>* nextPtr);
};
#endif
DoubleNode.cpp:
#include "DoubleNode.h"
template<class ItemType>
DoubleNode<ItemType>::DoubleNode(const ItemType& anItem, DoubleNode<ItemType>* prevPtr, DoubleNode<ItemType>* nextPtr) :
item(anItem), prev(prevPtr), next(nextPtr)
{
}
template<class ItemType>
DoubleNode<ItemType>::~DoubleNode()
{
this->prev = this->next = nullptr;
}
template<class ItemType>
ItemType DoubleNode<ItemType>::getItem() const
{
return this->item;
}
template<class ItemType>
DoubleNode<ItemType>* DoubleNode<ItemType>::getPrev() const
{
return this->prev;
}
template<class ItemType>
DoubleNode<ItemType>* DoubleNode<ItemType>::getNext() const
{
return this->next;
}
template<class ItemType>
void DoubleNode<ItemType>::setPrev(DoubleNode<ItemType>* prevPtr)
{
this->prev = prevPtr;
}
template<class ItemType>
void DoubleNode<ItemType>::setNext(DoubleNode<ItemType>* nextPtr)
{
this->next = nextPtr;
}
These two files were provided by my professor, and I need to implement another class called DoubleListInterface.h. I'm working on that right now, but I don't really know if I've even created the nodes right.
Here's my DoubleList.cpp insertFront implementation so far:
template<class ItemType>
bool DoubleList<ItemType>::insertFront(const ItemType& newEntry)
{
DoubleNode<ItemType>* n; // Creating pointer to node
DoubleNode<ItemType>* head;
DoubleNode<ItemType>* tail;
// If list is empty, this is the first node
if (itemCount == 0){
n = new DoubleNode<ItemType>; // Creating node
n->this->item(newEntry); // Putting item in node
n->prev = NULL; // First node, so prev is null
head = n; // Both head and tail would be at this node
tail = n;
itemCount++; // Increment itemCount
}
else{
DoubleNode<ItemType>* temp = new node; // Creating a filling new node
temp->this->item(newEntry);
temp->this->setPrev(head->this->getPrev()); // Set prev to the prev of head pointer
temp->this->getNext() = this->head; // Make next point to the head
head->this->getPrev() = temp; // Point prev of the old head node to the newly created node
head = temp; // Temp is the new head
delete temp; // Delete temp pointer
temp = NULL;
itemCount++; // Increment intemCount
}
return true;
}
I get a lot of errors when I run this, the majority of which are "expected unqualified-id before 'this'" on every place that I use a this pointer. Don't really know what that means either, but I'd really like to know if I'm creating the nodes right. Thanks for anything you can contribute.
You can't point to this.
For example, you wrote
temp->this->item(newEntry);
The correct way to do this is
temp->item(newEntry);
So i am coding a browser tab structure, and i have 5 custom class, Stack, LinkedList, Node(for linked list), Tab and Browser.
LinkedList and Stack works fine on their own, but when i construct a LinkedList in Browser's constructer i get error. So in my main i only call Browser().Here are the codes:
LinkedList<T>::LinkedList(){
front=NULL;
back=NULL;
}`
Node<T>::Node(){
prev=NULL;
next=NULL;
data=T();
}
Stack<T>::Stack(int capacity){ //capacity is optional, this is the default constructor.
this->capacity=capacity;
this->size=0;
this->items=new T[capacity];
}
`
Browser(){
selected = NULL;
//print browser link construction starts
pages= LinkedList<Tab>(); //This line gives the error.
closedPages= Stack<Tab>();
curr_index=-1;
tab_count=0;
}
Tab(){
current_page="";
prevPages=Stack<string>();
nextPages=Stack<string>();
closed_index=-1;
}
What is even funnier is that when i do print insertion, what i see is it first starts and finishes a link construction(without doing any tab construction in between), then does bunch of stack and tab construction, THEN prints the "browser link construction starts" and then goes in to and finishes another link construction and then gives seg fault. So it goes in to link construction twice even tough i hoped it would do only once?
Thanks, and sorry in advance if it is something extremly easy/stupid.
EDIT1: Full LinkedList Code
#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_
#include <iostream>
#include <cstddef>
#include <stdexcept>
#include "Node.hpp"
using namespace std;
template <class T>
class LinkedList {
private:
/* pointer to the first node */
Node<T>* front;
/* pointer to the last node */
Node<T>* back;
public:
LinkedList();
LinkedList(const LinkedList<T>& ll);
LinkedList<T>& operator=(const LinkedList<T>& ll);
~LinkedList();
/* returns the first node of the linked list */
Node<T>& getFront() const;
/* returns the last node of the linked list */
Node<T>& getBack() const;
/* returns the node in given "pos"ition of the linked list */
Node<T>& getNodeAt(int pos) const;
/* returns the pointer of the node in given
"pos"ition of the linked list */
Node<T>* getNodePtrAt(int pos) const;
/* inserts a new node containing "data"
after the node "prev"
*/
void insert(Node<T>* prev, const T& data);
/* inserts a new node containing "data"
at "pos"ition in the linked list
*/
void insertAt(int pos, const T& data);
/* erases the given "node" from the linked list */
void erase(Node<T>* node);
/* erases the node in given "pos"ition from the linked list */
void eraseFrom(int pos);
/* clears the contents of the linked list */
void clear();
/* inserts a new node containing "data"
to the front of the linked list
*/
void pushFront(const T& data);
/* inserts a new node containing "data"
to the back of the linked list
*/
void pushBack(const T& data);
/* removes the first node */
void popFront();
/* removes the last node */
void popBack();
/* returns true if the list is empty, false otherwise */
bool isEmpty() const;
/* returns the number of items in the list */
size_t getSize() const;
/* prints the contents of the linked list
one node data per line
assumes the objects in the node have operator<< overloaded
*/
void print() const;
};
template <class T>
LinkedList<T>::LinkedList(){
cout << "list construction starts" << endl;
front=NULL;
back=NULL;
cout << "list construction ends" << endl;
}
//COPY AND ASSIGMENT
template<class T>
LinkedList<T>::LinkedList(const LinkedList<T>& ll){
*this=ll;
}
template<class T>
LinkedList<T>& LinkedList<T>::operator=(const LinkedList<T>& ll){
clear();
Node<T>* temp=&(ll.getFront());
while(temp->getNext()!=NULL){
pushBack(temp->getData());
temp->setNext(temp->getNext());
}
pushBack(temp->getData());
return *this;
}
template<class T>
LinkedList<T>::~LinkedList(){
clear();
}
template <class T>
Node<T>& LinkedList<T>::getFront() const{
return *front;
}
template <class T>
Node<T>& LinkedList<T>::getBack() const{
return *back;
}
template <class T>
Node<T>& LinkedList<T>::getNodeAt(int pos) const{
if(pos<0 or pos>=getSize()){
throw out_of_range("Bad Input");
}
Node<T>* retval=front;
for(int i=0;i<pos;i++){
retval=retval->getNext();
}
return *retval;
}
template <class T>
Node<T>* LinkedList<T>::getNodePtrAt(int pos) const{
if(pos<0 or pos>getSize()){
throw out_of_range("Bad Input");
}
Node<T>* retval=front;
for(int i=0;i<pos;i++){
retval=retval->getNext();
}
return retval;
}
template <class T>
void LinkedList<T>::insert(Node<T>* prev,const T& data){
if(prev==NULL){
pushFront(data);
}
else if(prev==back){
pushBack(data);
}
else{
Node<T>* newNode=new Node<T>();
newNode->setData(data);
prev->getNext()->setPrev(newNode);
newNode->setNext(prev->getNext());
newNode->setPrev(prev);
prev->setNext(newNode);
}
}
template <class T>
void LinkedList<T>::insertAt(int pos,const T& data){
if(pos==0){
pushFront(data);
}
else if(pos==getSize()){
pushBack(data);
}
else{
Node<T>* tmp=getNodePtrAt(pos);
Node<T> newNode;
newNode.setData(data);
tmp->getPrev()->setNext(&newNode);
newNode.setNext(tmp);
newNode.setPrev(tmp->getPrev());
tmp->setPrev(&newNode);
}
}
template <class T>
void LinkedList<T>::pushFront(const T& data){
Node<T>* newNode=new Node<T>();
newNode->setData(data);
if(front==NULL){
front=newNode;
back=newNode;
}
else {
newNode->setNext(front);
front->setPrev(newNode);
front=newNode;
newNode->setPrev(NULL);
}
}
template <class T>
void LinkedList<T>::pushBack(const T& data){
Node<T>* newNode=new Node<T>();
newNode->setData(data);
if(front==NULL){
front=newNode;
back=newNode;
}
else {
newNode->setPrev(back);
back->setNext(newNode);
back=newNode;
newNode->setNext(NULL);
}
}
template <class T>
void LinkedList<T>::erase(Node<T>* node){
if(node==front){
popFront();
}
if(node==back){
popBack();
}
else {
node->getNext()->setPrev(node->getPrev());
node->getPrev()->setNext(node->getNext());
node->setNext(NULL); node->setPrev(NULL);
}
delete node;
}
template <class T>
void LinkedList<T>::eraseFrom(int pos){
Node<T>* tmp=getNodePtrAt(pos);
erase(tmp);
}
template <class T>
void LinkedList<T>::clear(){
while(!isEmpty()){
popFront();
}
}
template <class T>
void LinkedList<T>::popFront(){
Node<T>* tmp;
tmp=front;
if(front==back){
front=NULL;
back=NULL;
}
else{
front=front->getNext();
front->setPrev(NULL);
}
delete tmp;
}
template <class T>
void LinkedList<T>::popBack(){
Node<T>* tmp;
tmp=back;
if(front==back){
front=NULL;
back=NULL;
}
else {
back=back->getPrev();
back->setNext(NULL);
}
delete tmp;
}
template <class T>
bool LinkedList<T>::isEmpty() const{
return front==NULL;
}
template <class T>
size_t LinkedList<T>::getSize() const{
if(front==NULL){
return 0;
}
size_t size=1;
Node<T>* current=front;
while(current->getNext()!=NULL){
size++;
current=current->getNext();
}
return size;
}
template <class T>
void LinkedList<T>::print() const{
Node<T>* current=front;
if(front!=NULL){
while(current->getNext()!=NULL){
cout << current->getData() << endl;
current=current->getNext();
}
cout << current->getData() << endl;
}
}
#endif
Your assignment operator appears to be problematic. In your Browser constructor I see this:
pages = LinkedList<Tab>();
This is actually unnecessary but is triggering your problem. Your 'pages' variable is already default constructed (which is why you see all that activity before the print statement) by the time your Browser constructor code begins. Then you perform the assignment which utilizes your assignment operator.
Your assignment operator is assuming that the source LinkedList object has data, but it does not. It is calling getFront() which dereferences 'front', which is NULL. You should check if it is empty first, which I see you have a method for already (isEmpty()).
How can I create a linked node so that each linked node contains 2 items in a single node? Im not sure if I'm going in the right direction. I have 2 private members in my class, and I'm not sure if I need 2 set functions or if I can have a single set function with 2 parameters. For example void setItem(const string& anItem, const string secondItem);
#ifndef _NODE
#define _NODE
#include<string>
using namespace std;
class Node
{
private:
string item; // A data item
Node* next; // Pointer to next node
public:
Node();
Node(const string& anItem);
Node(const string& anItem, Node* nextNodePtr);
void setItem(const string& anItem);
void setNext(Node* nextNodePtr);
string getItem() const ;
Node* getNext() const ;
}; // end Node
#include "Node.cpp"
#endif
This is my Node.cpp file:
#include "Node.h"
#include <cstddef>
#include<string>
using namespace std;
Node::Node() : next(nullptr)
{
} // end default constructor
Node::Node(const string& anItem) : item(anItem), next(nullptr)
{
} // end constructor
Node::Node(const string& anItem, Node* nextNodePtr) :
item(anItem), next(nextNodePtr)
{
} // end constructor
void Node::setItem(const string& anItem)
{
item = anItem;
} // end setItem
void Node::setNext(Node* nextNodePtr)
{
next = nextNodePtr;
} // end setNext
string Node::getItem() const
{
return item;
} // end getItem
Node* Node::getNext() const
{
return next;
} // end getNext
For me, I'd go for two public functions for setting the two items of the node. One function will modify only one item, while the other function will modify the two item. Like:
// Function that will only set one item
void Node::setIndexItem(const int propNum, const string val)
{
if (propNum == 1) { // You may use 0 for the first item
this.item = val;
} else if (propNum == 2) { // You may use 1 for the second item
this.item2 = val;
} else {
// You may want to raise an exception here. Depends on you really.
}
}
// Function that will set the two items
void Node::setItems(const string val1, const string val2)
{
this.item = val1;
this.item2 = val2;
}
In your case, I would create a dedicated class for the data
struct DataNode
{
std::string key;
std::string value;
};
That separates class responsabilities (List may be focussed to link node).
That would allow you to modify data type without changing your class List (a templated list would be even better, but out of scope).
And then, your Node class would be something like:
class Node
{
private:
DataNode data;
Node* next; // Pointer to next node // I assume you can't use unique_ptr :-/
public:
Node();
Node(const DataNode& data);
Node(const DataNode& data, Node* nextNodePtr);
// Rule of 3
Node(const Node& rhs);
~Node();
Node& operator =(const Node& rhs);
// data accessor
void setItem(const DataNode& data);
const DataNode& getItem() const;
DataNode& getItem();
// Internal utility
void setNext(Node* nextNodePtr);
const Node* getNext() const;
Node* getNext();
};
I added a non-const version of the getter to allow modifying part of the item:
node.getItem().value = "new value";
I'm writing list and iterator classes function and I'm almost done, but I get some errors in the main file, that when I write the list remove_all function, but when I delete it there is no error anywhere, I don't know why!! Also, actually I'm not sure about my Iterator operators and the bool Iterator::is_item()
Any help is appreciated. Thanks
here is my codes:
Node.h
pragma once
namespace list_1
{
template <typename T>
struct Node
{
T data;
Node<T> *next;
// Constructor
// Postcondition:
Node<T> (T d);
};
template <typename T>
Node<T>::Node(T d)
{
}
}
Iterator.h
// Template CLASS PROVIDED: Iterator
#pragma once
#include "Node.h"
namespace list_1
{
template<typename T>
class Iterator
{
public:
Iterator<T> (Node<T> *np);
// precondition: is_item is true
// post condition n points to the next item in the list
void operator++();
// precondition:
// postcondition: returns true if there is a valid item
bool is_item();
// precondition: is_item == true
// postcondition returns data that n is pointing at
T operator* ();
private:
Node<T>* n;
};
List.h
#ifndef LIST_H
#define LIST_H
#include "Node.h"
#include "Iterator.h"
namespace list_1
{
template <typename T>
class list
{
public:
// CONSTRUCTOR
list( );
// postcondition: all nodes in the list are destroyed.
~list();
// MODIFICATION MEMBER FUNCTIONS
//postcondition: entry is added to the front of the list
void insert_front(const T& entry);
//postcondition: entry is added to the back of the list
void add_back(const T& entry);
// postcondition: all nodes with data == entry are removed from the list
void remove_all(const T& entry);
// postcondition: an iterator is created pointing to the head of the list
Iterator<T> begin(void);
// CONSTANT MEMBER FUNCTIONS
// postcondition: the size of the list is returned
int size( ) const;
private:
Node<T>* head;
};
Your syntax errors are because you are missing a couple closing curly brackets on your "else" blocks at the end of the remove_all function.
Try replacing it with this
(edit: included the suggestion about cout mentioned in the comments above)
void list<T>::remove_all(const T& entry)
{
if(head == 0)
{
std::cout<<" node cannot be delted";
}
else
{
Node<T> *curr = head;
Node<T> *trail = 0;
while( curr != 0)
{
if(curr->entry == entry)
{
break;
}
else
{
trail = curr;
curr = curr->next;
}
}
if(curr == 0)
{
std::cout<<" Node " << entry<< " is not found";
}
else
{
if ( head == curr)
{
head = head->next;
}
else
{
trail->next = curr->next;
}
} // missing this one
delete curr;
} // and this one as well
}
I am working on a template for a binary search tree and I am getting the error below. I know there are similar post but I can't figure this thing out. Templates are definitely a weak subject for me so I think I am missing some fundamental semantic thing but I can put my finger on it. Below is the error than after that are the files of the program. If anyone could point me in the right direction I would really appreciate it.
Error 1 error LNK2019: unresolved external symbol "private: bool __thiscall Tree::insertHelper(class TreeNode * &,int)" (?insertHelper#?$Tree#H##AAE_NAAPAV?$TreeNode#H##H#Z) referenced in function "public: bool __thiscall Tree::insert(int)" (?insert#?$Tree#H##QAE_NH#Z) C:\Users\wm\documents\visual studio 2012\Projects\binaryTree\binaryTree\main.obj
-basic main for testing
#include "BinarySearchTree.h"
#include "TreeNode.h"
#include <iostream>
using namespace std;
int main()
{
Tree<int> test;
test.insert(55);
return 0;
}
-tree template
#include <iostream>
#include "TreeNode.h"
using namespace std;
template< class ItemType >
class Tree {
public:
Tree();
~Tree();
bool isEmpty() const;
void makeEmpty();
bool insert( ItemType newItem);
bool retrieve( ItemType searchItem, ItemType & foundItem );
bool deleteItem (ItemType deleteItem);
void print();
private:
TreeNode< ItemType > * rootPtr; // pointer to the root
//utility functions
void printHelper( TreeNode< ItemType > * );
bool insertHelper(TreeNode< ItemType > * & node, ItemType item);
bool deleteHelper( TreeNode< ItemType > * & , ItemType );
void deleteNode( TreeNode<ItemType > * & );
bool retrieveHelper( ItemType, TreeNode< ItemType > * & , ItemType & );
};
template<class ItemType>
Tree<ItemType>::Tree()
{
rootPtr = NULL;
}
template<class ItemType>
Tree<ItemType>::~Tree()
{
makeEmpty();
}
template<class ItemType>
bool Tree<ItemType>::isEmpty() const
//Returns True if the tree is empty, otherwise returns false
//Postcondition: Tree is unchanged.
{
if(rootPtr == NULL)
{
return true;
}
else
{
return false;
}
}
template<class ItemType>
void Tree<ItemType>::makeEmpty()
//Makes the tree empty if it is not empty already.
//Preconditions: The tree exists.
//Postconditions: Tree is now empty. Any dynamically allocated memory which is no longer used is returned to the system.
{
return;
}
template<class ItemType>
bool Tree<ItemType>::insert( ItemType newItem)
// Inserts a copy of newItem in the tree.
//Precondition: The tree exists and has binary search property.
//Postcondition: if the tree already has an item where item == newItem, the function returns false and the trre is unchanged.
//Otherwise, the newItem is inserted in the tree preserving and the binary search property is maintained.
{
if(rootPtr == NULL)
{
rootPtr->data = newItem;
return true;
}
else
{
return insertHelper(rootPtr, newItem);
}
}
template<class ItemType>
bool insertHelper( TreeNode< ItemType > * & node, ItemType item)
{
if( item < node->data)//left
{
if(node->leftPtr == NULL)
{
node->leftPtr = new TreeNode<ItemType>(item);
return true;
}
else
{
return insertHelper(node->leftPtr,item);
}
}
else if(node->data < item)//right
{
if(node->righChild == NULL)
{
node->rightPtr = new TreeNode<ItemType>(item);
return true;
}
else
{
return insertHelper(node->rightPtr,item);
}
}
else// same value
{
return false;
}
}
template<class ItemType>
bool Tree<ItemType>::retrieve( ItemType searchItem, ItemType & foundItem )
// Given a searchItem, it tries to retrieve as foundItem, an item in the tree where the item == searchItem.
// Precondition:The tree exists and has the binary search property.
// Postcondition: If the tree already has an item where item == searchItem, foundItem is set to that item, and the function returns true.
// If the tree has no such item, the function returns false and foundItem remains unchanged. The tree is unchanged.
{
}
template<class ItemType>
bool Tree<ItemType>::deleteItem (ItemType deleteItem)
// Given a deleteItem, it deltes from the tree any item where item == deleteItem.
// Precondition: Tree exists and has binary search property.
// Postcondition: If the tree has an item where item == deleteItem, that item is removed from the tree, and the function returns true, and
// the binary search property is maintained. If the tree has no such item, the function returns false and the tree remains unchanged.
{
}
template<class ItemType>
void Tree<ItemType>::print()
// Prints the items in the tree in ascending order to the screen
// Precondition: The tree exists and has binary search property.
// Postcondition: The items have been printed in ascending order and the tree is unchanged
{
}
template<class ItemType>
void printHelper( TreeNode< ItemType > * )
{
}
template<class ItemType>
bool deleteHelper( TreeNode< ItemType > * & , ItemType )
{
}
template<class ItemType>
void deleteNode( TreeNode<ItemType > * & )
{
}
template<class ItemType>
bool retrieveHelper( ItemType, TreeNode< ItemType > * & , ItemType & )
{
}
-treenode
#ifndef TREENODE_H
#define TREENODE_H
template< class ItemType > class Tree; // forward declarations
template<class ItemType>
class TreeNode {
friend class Tree< ItemType >; // make Tree a friend
public:
TreeNode( ItemType ); // constructor
TreeNode(); // constructor with data uninitialized
ItemType getData() const; // return data in the node
private:
ItemType data;
TreeNode< ItemType > *leftPtr;
TreeNode< ItemType > *rightPtr;
};
// Constructor
template<class ItemType>
TreeNode< ItemType >::TreeNode( ItemType newItem )
{
data = newItem;
leftPtr = NULL;
rightPtr = NULL;
}
template<class ItemType>
TreeNode< ItemType >::TreeNode( )
{
leftPtr = NULL;
rightPtr = NULL;
}
// Return a copy of the data in the node
template< class ItemType >
ItemType TreeNode< ItemType >::getData() const
{
return data;
}
#endif
Heh. The problem is that you forgot the scoping qualifier Tree<ItemType>:: in front of the function name for insertHelper.
Just do this:
template<class ItemType>
bool Tree<ItemType>::insertHelper( TreeNode< ItemType > * & node, ItemType item)
By the way, the linker error should suggest to you that this is the problem. First of all, you know that you have a link problem, not a compile problem. Second, you know the symbol that can't be found is *Tree<ItemType>::*insertHelper(...). Third, you know that a call to that function was successfully compiled in Tree<ItemType>::insert, which means the compiler found and parsed the declaration for the insertHelper method without problem. The only possible explanation for the linker not being able to find the actual object code for the method is that the definition of the function either doesn't exist or doesn't have the same name that you declared it as!
Here:
if(rootPtr == NULL)
{
rootPtr->data = newItem;
return true;
}
If rootPtr is NULL then rootPtr->data is not valid.
Maybe you meant:
if(rootPtr == NULL)
{
rootPtr = new TreeNode<ItemType>(newItem);
}