/* * FILE: list.h - List ADT template class definition * Uses linked-list representation * */ #ifndef __LIST #define __LIST #include #include using namespace std; template class list; template class node { // All data members *and* constructor are private. Why? private: // Constructor node( const item&, node* ); item data; node* link; // Why does this need to be here???? friend ostream& operator<<(ostream &,const list &); // Means only lists, which are containers of nodes, can access into nodes friend class list; }; template class list { public: // Construct an empty list list(); // Destroy a list by eliminating all nodes ~list(); // Set the list's data to initial state void init(); // Destroy all nodes! void destroy(); // Insertion void insertFirst(const item&); void insertLast(const item&); void insertInOrder(const item&); // Single node removal void removeFirst(); void removeLast(); void removeInOrder(const item&); // Inspectors item firstValue(); item lastValue(); int size(); private: node* first; node* last; int count; friend ostream& operator<<(ostream &,const list &); }; // Construct a node template node::node( const item& itm, node* ptr ) { data = itm; link = ptr; } // Construct a list template list::list() { init();} // Cause a list's nodes to be freed template list::~list() {destroy();} // Set data members to initialization condition template void list::init() { first = last = NULL; count = 0; } // Reset list template void list::destroy() { node* doomed; while ( first != NULL ) { doomed = first; first = first->link; delete doomed; } init(); } // Insert at head template void list::insertFirst( const item& itm ) { assert((first = new node(itm,first)) != NULL); if ( last == NULL ) { last = first; } count++; } // Insert at Tail template void list::insertLast( const item& itm ) { if ( last == NULL ) { insertFirst( itm ); } else { assert( (last = last->link = new node(itm, NULL)) != NULL ); count++; } } // Insert in order template void list::insertInOrder(const item &elt) { if ( !first || elt < first->data ) insertFirst(elt); else { node* p = first; node* trailp = NULL; while ( p != NULL && elt > p->data ) { // Two pointer search trailp = p; p = p->link; } trailp->link = new node(elt,p); } } // Remove from head template void list::removeFirst() { assert( size() > 0 ); node* doomed = first; if ( first == last ) first = last = NULL; else first = first->link; delete doomed; count--; } // Remove from tail template void list::removeLast() { node* doomed = last; if ( first == last ) first = last = NULL; else { node* tmp; for ( tmp = first; tmp->link != last; tmp = tmp->link ) ; tmp->link = NULL; last = tmp; } delete doomed; count--; } // Remove a node in the list: No precondition on node being in list // Precondition: List not empty template void list::removeInOrder(const item &elt) { node* p = first; node* trailp = NULL; // Search for data while (p!=NULL && p->data!=elt) { trailp = p; p = p->link; } if (p==NULL) // x is not in the list; return return; if ( p == first ) first = first->link; // x is first in the list else trailp->link = p->link; // x is farther down in the list delete p; } // Return copy of data in first node template item list::firstValue() { assert( size() > 0 ); return first->data; } // Return copy of data in last node template item list::lastValue() { assert( size() > 0 ); return last->data; } // Return number of nodes template int list::size() { return count;} // Print template ostream &operator<<(ostream &out,const list &l) { for ( node *p=l.first;p;p=p->link) out << p->data << endl; return(out); } #endif // Things to try: // Implement [] to get ith element // Implement copy constructor and = (deep copy) // Implement insertLast() as += // Implement + to concatenate two linked lists // Implement other overloaded operators // Iterators?