annotate algs4-c++/src/Stack.hpp @ 27:80ca1973e3bd

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