#ifndef DEQUE_H_ #define DEQUE_H_ 1 // Oldham, Jeffrey D. // 2000Mar25 // CS1321 // // Modified by: // Massingill, Berna L. // 2001Apr // Deque Implementation // This class implements a deque, a Double-Ended QUEue. ("Deque" is // pronounced "deck.") This data structure supports insertion and // deletion at both the front and the back in a constant amount of // time. In contrast, vectors support constant-time insertion and // deletion only at the back, i.e., right. // We implement a deque using a doubly-linked list. #include "dll.h" #include #include class deque { public: typedef dll::item_type item_type; typedef unsigned long size_type; // No need for a constructor, destructor, copy constructor, // or assignment operator. // ---- Insertion routines ----------------------------------------- // Post: i has been added to front of deque. void push_front(const item_type & i) { lst.insert(lst.begin(), i); return; } // Post: i has been added to back (end) of deque. void push_back(const item_type & i) { lst.insert(lst.end(), i); return; } // ---- Removal routines ------------------------------------------- // Pre: deque is not empty. // Post: front element has been removed. void pop_front(void) { assert(!empty()); lst.erase(lst.begin()); } // Pre: deque is not empty. // Post: back element has been removed. void pop_back(void) { assert(!empty()); lst.erase(lst.pred(lst.end())); } // ---- Access routines -------------------------------------------- // We define two version of each routine here. The first // returns a reference that the calling program can use to // modify the deque (e.g., d.front() = 'a'); the second // is declared 'const' and returns a 'const' reference, so // the calling program cannot modify the deque. This // could be useful in a calling program in which the deque // is a 'const' parameter, e.g. // Pre: deque is not empty. // Post: returns reference to front element. item_type& front(void) { assert(!empty()); return lst.begin()->itm; } // Pre: deque is not empty. // Post: returns reference to front element. const item_type& front(void) const { assert(!empty()); return lst.begin()->itm; } // Pre: deque is not empty. // Post: returns reference to back element. item_type& back(void) { assert(!empty()); return lst.pred(lst.end())->itm; } // Pre: deque is not empty. // Post: returns reference to back element. const item_type& back(void) const { assert(!empty()); return lst.pred(lst.end())->itm; } // Pre: deque is not empty. // Post: returns reference to i-th element (elements // are numbered starting with 0). item_type& operator[](const size_type i) { dll::link * l; size_type count; for (l = lst.begin(), count = 0; l != lst.end() && count < i; l = lst.succ(l), ++count) ; // notice empty loop body assert (l != lst.end()); // would mean count >= length return l->itm; } // Pre: deque is not empty. // Post: returns reference to i-th element (elements // are numbered starting with 0). const item_type& operator[](const size_type i) const { dll::link * l; size_type count; for (l = lst.begin(), count = 0; l != lst.end() && count < i; l = lst.succ(l), ++count) ; // notice empty loop body assert (l != lst.end()); // would mean count >= length return l->itm; } // ---- Other routines --------------------------------------------- // Check for empty. // Post: returns true if deque is empty, false otherwise. bool empty(void) const { return lst.begin() == lst.end(); } // Find size. // Post: returns number of elements in deque. size_type size(void) const { dll::link * l; size_type count; for (l = lst.begin(), count = 0; l != lst.end(); l = lst.succ(l), ++count) ; // notice empty loop body return count; } // Output operator. // Post: elements of dq have been written to "out". friend ostream& operator<<(ostream& out, const deque & dq) { for (dll::link * l = dq.lst.begin(); l != dq.lst.end(); l = dq.lst.succ(l)) out << l->itm; return out; } private: dll lst; }; #endif // DEQUE_H_