annotate algs4-c++/src/Queue.hpp @ 24:028689700a47

Updated Queue to have a const_iterator too and to support a copy constructor (problem 1.3.41
author Eris Caffee <discordia@eldalin.com>
date Tue, 23 Jun 2015 14:52:17 -0500
parents a149b424b4e2
children 3cdac4c29445
rev   line source
discordia@16 1 // Linked list based queue after Sedgewick and Wayne, Algorithms 4th ed, Algorithm 1.3
discordia@16 2
discordia@8 3 #ifndef QUEUE_HPP
discordia@8 4 #define QUEUE_HPP
discordia@8 5
discordia@8 6 #include <cstddef>
discordia@16 7 #include <cassert>
discordia@24 8 #include <iterator>
discordia@8 9
discordia@8 10 template <typename T>
discordia@8 11 class Queue {
discordia@8 12
discordia@9 13 private:
discordia@8 14
discordia@8 15 ////////////////////////////////////
discordia@8 16 class Node {
discordia@8 17 public:
discordia@8 18 T item;
discordia@8 19 Node *next;
discordia@8 20 };
discordia@8 21
discordia@9 22 public:
discordia@8 23
discordia@8 24 ////////////////////////////////////
discordia@24 25 class iterator : public std::iterator<std::forward_iterator_tag, T> {
discordia@8 26
discordia@8 27 public:
discordia@8 28
discordia@8 29 iterator( Node *c );
discordia@8 30
discordia@8 31 iterator& operator++();
discordia@8 32 iterator operator++(int);
discordia@8 33
discordia@8 34 T operator*();
discordia@8 35 bool operator!=( typename Queue<T>::iterator );
discordia@8 36
discordia@8 37 private:
discordia@8 38
discordia@8 39 Node *curr;
discordia@8 40 };
discordia@8 41
discordia@8 42 ////////////////////////////////////
discordia@8 43
discordia@24 44 class const_iterator : public std::iterator<std::forward_iterator_tag, T> {
discordia@24 45
discordia@24 46 public:
discordia@24 47
discordia@24 48 const_iterator( const Node *c );
discordia@24 49
discordia@24 50 const_iterator& operator++();
discordia@24 51 const_iterator operator++(int);
discordia@24 52
discordia@24 53 const T operator*();
discordia@24 54 bool operator!=( typename Queue<T>::const_iterator );
discordia@24 55
discordia@24 56 private:
discordia@24 57
discordia@24 58 const Node *curr;
discordia@24 59 };
discordia@24 60
discordia@24 61 ////////////////////////////////////
discordia@24 62
discordia@8 63 Queue( void );
discordia@8 64 ~Queue( void );
discordia@8 65
discordia@24 66 // 1.3.41 Copy constructor.
discordia@24 67 Queue( const Queue<T> &q );
discordia@24 68
discordia@8 69 void enqueue( T &item );
discordia@8 70 T dequeue( void );
discordia@8 71
discordia@8 72 bool is_empty( void );
discordia@8 73 size_t size( void );
discordia@8 74
discordia@8 75 iterator begin( void );
discordia@8 76 iterator end( void );
discordia@24 77 const_iterator begin( void ) const;
discordia@24 78 const_iterator end( void ) const;
discordia@8 79
discordia@9 80
discordia@8 81 private:
discordia@8 82
discordia@8 83 size_t N;
discordia@8 84 Node *first;
discordia@8 85 Node *last;
discordia@8 86
discordia@8 87 };
discordia@8 88
discordia@8 89
discordia@16 90 template <typename T>
discordia@16 91 Queue<T>::Queue( void ) :
discordia@16 92 N (0),
discordia@16 93 first (nullptr),
discordia@16 94 last (nullptr)
discordia@16 95 {
discordia@16 96 }
discordia@24 97
discordia@24 98 // 1.3.41
discordia@24 99 template <typename T>
discordia@24 100 Queue<T>::Queue( const Queue<T> &q ) :
discordia@24 101 N (0),
discordia@24 102 first (nullptr),
discordia@24 103 last (nullptr)
discordia@24 104 {
discordia@24 105 for ( auto it = q.begin(); it != q.end(); ++it ) {
discordia@24 106 T item = *it;
discordia@24 107 this->enqueue( item );
discordia@24 108 }
discordia@24 109 }
discordia@16 110
discordia@16 111 template <typename T>
discordia@16 112 Queue<T>::~Queue( void ) {
discordia@16 113 assert( N == 0 ); // Catch the potential memory leak.
discordia@16 114 while ( first ) {
discordia@16 115 Node *next = first->next;
discordia@16 116 delete first;
discordia@16 117 first = next;
discordia@16 118 }
discordia@16 119 }
discordia@16 120
discordia@16 121 template <typename T>
discordia@16 122 void Queue<T>::enqueue( T &item ) {
discordia@16 123 Node * node = new Node();
discordia@16 124 node->item = item;
discordia@16 125 node->next = nullptr;
discordia@16 126
discordia@16 127 if ( last ) {
discordia@16 128 last->next = node;
discordia@16 129 last = node;
discordia@16 130 }
discordia@16 131 else {
discordia@16 132 last = first = node;
discordia@16 133 }
discordia@16 134
discordia@16 135 N++;
discordia@16 136 }
discordia@16 137
discordia@16 138 template <typename T>
discordia@16 139 T Queue<T>::dequeue( void ) {
discordia@16 140 assert( N > 0 );
discordia@16 141
discordia@16 142 T item = first->item;
discordia@16 143
discordia@16 144 Node *old = first;
discordia@16 145 first = first->next;
discordia@16 146 delete old;
discordia@16 147 N--;
discordia@16 148
discordia@16 149 if ( ! first )
discordia@16 150 last = nullptr;
discordia@16 151
discordia@16 152 return item;
discordia@16 153 }
discordia@16 154
discordia@16 155 template <typename T>
discordia@16 156 bool Queue<T>::is_empty( void ) {
discordia@16 157 return N == 0;
discordia@16 158 }
discordia@16 159
discordia@16 160 template <typename T>
discordia@16 161 size_t Queue<T>::size( void ) {
discordia@16 162 return N;
discordia@16 163 }
discordia@16 164
discordia@16 165 template <typename T>
discordia@16 166 typename Queue<T>::iterator Queue<T>::begin( void ) {
discordia@16 167 return Queue<T>::iterator( first );
discordia@16 168 }
discordia@16 169
discordia@16 170 template <typename T>
discordia@16 171 typename Queue<T>::iterator Queue<T>::end( void ) {
discordia@16 172 return Queue<T>::iterator( nullptr );
discordia@16 173 }
discordia@16 174
discordia@24 175 template <typename T>
discordia@24 176 typename Queue<T>::const_iterator Queue<T>::begin( void ) const {
discordia@24 177 return Queue<T>::const_iterator( first );
discordia@24 178 }
discordia@24 179
discordia@24 180 template <typename T>
discordia@24 181 typename Queue<T>::const_iterator Queue<T>::end( void ) const {
discordia@24 182 return Queue<T>::const_iterator( nullptr );
discordia@24 183 }
discordia@24 184
discordia@16 185
discordia@16 186 ////////////////////////////////////////////////////////////////////////////////
discordia@16 187
discordia@16 188 template <typename T>
discordia@16 189 Queue<T>::iterator::iterator( Node *c ) :
discordia@16 190 curr (c)
discordia@16 191 {
discordia@16 192 }
discordia@16 193
discordia@16 194 template <typename T>
discordia@16 195 typename Queue<T>::iterator & Queue<T>::iterator::operator++() {
discordia@16 196 if ( this->curr != nullptr ) {
discordia@16 197 this->curr = this->curr->next;
discordia@16 198 }
discordia@16 199 return *this;
discordia@16 200 }
discordia@16 201
discordia@16 202 template <typename T>
discordia@16 203 typename Queue<T>::iterator Queue<T>::iterator::operator++( int ) {
discordia@16 204 auto t = Queue<T>::iterator( *this );
discordia@16 205
discordia@16 206 if ( this->curr != nullptr ) {
discordia@16 207 this->curr = this->curr->next;
discordia@16 208 }
discordia@16 209 return t;
discordia@16 210 }
discordia@16 211
discordia@16 212 template <typename T>
discordia@16 213 T Queue<T>::iterator::operator*() {
discordia@16 214 return this->curr->item;
discordia@16 215 }
discordia@16 216
discordia@16 217 template <typename T>
discordia@16 218 bool Queue<T>::iterator::operator!=( typename Queue<T>::iterator other ) {
discordia@16 219 return this->curr != other.curr;
discordia@16 220 }
discordia@16 221
discordia@24 222 ////////////////////////////////////////////////////////////////////////////////
discordia@24 223
discordia@24 224 template <typename T>
discordia@24 225 Queue<T>::const_iterator::const_iterator( const Node *c ) :
discordia@24 226 curr (c)
discordia@24 227 {
discordia@24 228 }
discordia@24 229
discordia@24 230 template <typename T>
discordia@24 231 typename Queue<T>::const_iterator & Queue<T>::const_iterator::operator++() {
discordia@24 232 if ( this->curr != nullptr ) {
discordia@24 233 this->curr = this->curr->next;
discordia@24 234 }
discordia@24 235 return *this;
discordia@24 236 }
discordia@24 237
discordia@24 238 template <typename T>
discordia@24 239 typename Queue<T>::const_iterator Queue<T>::const_iterator::operator++( int ) {
discordia@24 240 auto t = Queue<T>::const_iterator( *this );
discordia@24 241
discordia@24 242 if ( this->curr != nullptr ) {
discordia@24 243 this->curr = this->curr->next;
discordia@24 244 }
discordia@24 245 return t;
discordia@24 246 }
discordia@24 247
discordia@24 248 template <typename T>
discordia@24 249 const T Queue<T>::const_iterator::operator*() {
discordia@24 250 return this->curr->item;
discordia@24 251 }
discordia@24 252
discordia@24 253 template <typename T>
discordia@24 254 bool Queue<T>::const_iterator::operator!=( typename Queue<T>::const_iterator other ) {
discordia@24 255 return this->curr != other.curr;
discordia@24 256 }
discordia@24 257
discordia@8 258
discordia@8 259 #endif
discordia@8 260