// File: LinkedList.h // Linked List class with List Iterator class #ifndef _LinkedList_ #define _LinkedList_ #include using namespace std; // Need to prototype template classes if they are to be friends template class LinkedList; template class ListIterator; /* // and also the friend...note <> in header declaration of << template ostream& operator<<(ostream&,LinkedList); */ template class node { private: node(eltType info= 0, node* link = NULL ) : data(info), next(link) {}; eltType data; node* next; friend class LinkedList; friend class ListIterator; }; template class LinkedList { public: // Construct empty LinkedList LinkedList(); // Construct deep copy of another LinkedList LinkedList(LinkedList&); // destroy LinkedList ~LinkedList(); // Assign another LinkedList to this LinkedList; deep copy LinkedList& operator=(const LinkedList&); // Is the LinkedList empty? bool empty(); bool find(eltType); // Ordered insert/remove void orderedInsert(eltType); void remove(eltType); private: // linked list pointer node* head; // Get a copy of a (deep) node node* copy(node *); // Free nodes of a linked list void destroy(node *); /* // Linked list to ostream friend ostream& operator<< <>(ostream&, LinkedList); */ // Needed to use a list iterator friend class ListIterator; }; template ostream& operator<<(ostream &os,const LinkedList &l); // Set up an iterator; // an object that provides a pointer to a linked list (in this case) template class ListIterator { public: // Construc a List Iterator ListIterator(const LinkedList &list); // Set current to point at the first node of ListRef void start(); // Is current null? bool more(); // Go to current->next void next(); // Get the value out of current's node eltType &value(); private: const LinkedList &ListRef; node *current; }; // Construct empty LinkedList template LinkedList::LinkedList() : head(NULL) {} // Copy constructor. copy() does the deep copy template LinkedList::LinkedList(LinkedList &cl) {head = copy( cl.head );} // Free all nodes template LinkedList::~LinkedList() {destroy(head);} // Assignment operator: copy() does the deep copy template LinkedList &LinkedList::operator =(const LinkedList& cl) { if (this != &cl) { destroy(head); head = copy(cl.head); } return *this; } // Place x into the list in order template void LinkedList::orderedInsert(eltType x) { if (empty() || x < head->data) head=new node(x,head); else // start at 2nd node...already checked first node { node* p = head -> next; // head; node* trailp = head; // NULL; while (p != NULL && x > p->data) { trailp = p; p = p->next; } trailp->next = new node(x,p); } } // Is this element in the linked list? template bool LinkedList::find(eltType x) { node *p = head; while (p != NULL && p->data != x) p = p->next; return (p != NULL && p->data == x); } // Inline: Look into this. template inline bool LinkedList::empty() {return (head == NULL);} // Remove a node in an ordered list // Pre: Node will be found template void LinkedList::remove(eltType x) { node* p = head; node* trailp = NULL; while ( p != NULL && p->data != x ) { trailp = p; p = p->next; } if (p == head) head = head->next; // x is first in the LinkedList else trailp->next = p->next; // x is farther down in the LinkedList delete p; } // Remove all nodes in the linked list, starting at l template void LinkedList::destroy(node *listPtr) { while (listPtr != NULL) { node *doomed = listPtr; listPtr = listPtr->next; delete doomed; } } // The deep copy. Copy the source list l, one node at a time template node* LinkedList::copy(node *listPtr) { if (listPtr != NULL) { node* first = NULL; // ptr to beginning of copy node* last = NULL; // ptr to last item in the copy first=last=new node(listPtr->data,NULL); for (node* source=listPtr->next;source!=NULL; source=source->next,last=last->next) { last->next = new node(source->data,NULL); } return(first); } return NULL; } // Output a linked list, using a list iterator template ostream& operator<<(ostream &os,const LinkedList &list) { ListIterator ListIt(list); for (ListIt.start(); ListIt.more(); ListIt.next()) os << ListIt.value() << " "; return os; } /* **************************************************************** ************** List Iterator Implementations ******************* ****************************************************************/ // Construct a list iterator. It consists of: // a reference to a linked list object // a pointer to the actual list, initially pointing to its head template ListIterator::ListIterator(const LinkedList &list): ListRef(list),current(NULL) {} // Set current to point at ListRef's head template void ListIterator::start(void) {current = ListRef.head;} // Is current at the end of the list? template bool ListIterator::more(void) {return current != NULL;} // Move current to next node // This function shouldn't be called until making sure more() returns true template void ListIterator::next(void) {current = current->next; } // Return data in current's node. // This function shouldn't be called until making sure more() returns true template eltType &ListIterator::value(void) {return current->data; } #endif