#ifndef DLL_H_ #define DLL_H_ 1 // Oldham, Jeffrey D. // 2000Mar13 // CS1321 // Modified by: // Massingill, Berna L. // 2001 March // Doubly-Linked List Implementation // This class implements a doubly-linked list. Each link is allocatd // from dynamic memory. The list is represented as a circular-linked // list with a sentinel link. #include #include // has assert() class dll { public: typedef char item_type; // for now -- "templatize" later class link { public: item_type itm; link * prev; // pointers to other links link * next; }; // Constructor. dll(void) { create(); return; } // Copy constructor. dll(const dll & d) { copy(d); return; } // Assignment operator. dll& operator=(const dll & d) { if (this != &d) { destroy(); copy(d); } return *this; } // Destructor. ~dll(void) { // Delete all the links. destroy(); } // Insert the item before the link. // Post: a link with value "i" has been added before link *pos. // returns pointer to newly-added link. link * insert(link * const pos, const item_type & i) { link * n = new link; n->itm = i; // Change new link's pointers. n->prev = pos->prev; n->next = pos; // Change the surrounding links' pointers. n->next->prev = n; n->prev->next = n; return n; } // Delete the specified link. // Pre: *pos is not the sentinel link. // Post: link *pos has been removed from the list. // returns pointer to link following *pos. link * erase(link * const pos) { assert(pos != sentinel); link * n = pos; // or we could have passed "pos" by value link * answer = n->next; // Change the surrounding links' pointers. n->prev->next = n->next; n->next->prev = n->prev; // Change new link's pointers (not actually necessary). n->prev = 0; n->next = 0; delete n; return answer; } // Get start of list (analogous to STL classes' begin()). // Post: returns pointer to first link in list (or to sentinel, // if list is empty). link * begin(void) const { return sentinel->next; } // Get past-end of list (analogous to STL classes' end()). // Post: returns pointer to sentinel link. link * end(void) const { return sentinel; } // Get predecessor link. // Post: returns pointer to link before *pos. link * pred(link * const pos) const { return pos->prev; } // Get successor link. // Post: returns pointer to link after *pos. // if *pos is the last link in the last, this function // should return the same thing as the end() function; // callers can determine "end of list" by comparing the // value returned by succ() to the value returned by // end(). link * succ(link * const pos) const { return pos-> next; } // Output operator. friend ostream & operator << (ostream & o, const dll & d) { for (link * p = d.begin(); p != d.end(); p = d.succ(p)) o << p->itm << ' '; return o; } private: link * sentinel; // sentinel (dummy) link, always present // Create an empty list. // Pre: sentinel does not point to anything; no "link" objects are // allocated for this list. // Post: sentinel points to the "sentinel" node, which is the only // link in the list. void create(void) { sentinel = new link; // sentinel->itm need not be set sentinel->prev = sentinel; sentinel->next = sentinel; return; } // Destroy this list. // Pre: sentinel points to sentinel link for list. // Post: all allocated "link" objects have been freed. void destroy(void) { while (sentinel->next != sentinel) erase(sentinel->next); delete sentinel; } // Copy the given list into this one. // Pre: sentinel does not point to anything; no "link" objects are // allocated for this list. // Post: list is a copy of list "d". void copy(const dll & d) { create(); for (link * pos = d.sentinel->next; pos != d.sentinel; pos = pos->next) insert(sentinel, pos->itm); return; } }; #endif // DLL_H_