00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 #ifndef __SEAL_BINTREE_H__ 00030 #define __SEAL_BINTREE_H__ 00031 00032 #include "list.h" 00033 #include "dataptr.h" 00034 #include "node.h" 00035 00036 namespace seal 00037 { 00038 00039 template <typename T> 00040 class BinTreeBreadthFirstIterator; 00041 00051 template <typename T> 00052 class CompleteBinaryTree : public Collection<T> 00053 { 00054 public: 00058 CompleteBinaryTree(void); 00059 00062 CompleteBinaryTree(const CompleteBinaryTree<T> &bt); 00063 00066 virtual ~CompleteBinaryTree(); 00067 00070 virtual bool isEmpty(void) const { if (*_sizePtr == 0) return true; else return false; } 00071 00074 virtual unsigned int size(void) const { return *_sizePtr; } 00075 00079 virtual AbstractIterator<T>* iteratorPtr(void) const 00080 { 00081 return new BinTreeBreadthFirstIterator<T>(_firstNodePtr->data); 00082 } 00083 00086 BinTreeBreadthFirstIterator<T> breadthFirstIterator(void) const 00087 { 00088 return BinTreeBreadthFirstIterator<T>(_firstNodePtr->data); 00089 } 00090 00093 virtual void pushBack(const T element); 00094 00097 virtual void popBack(void); 00098 00101 virtual void purge(void); 00102 00105 virtual T& first(void) throw (EmptyCollectionException); 00106 00109 virtual const T& first(void) const throw (EmptyCollectionException); 00110 00113 virtual T& last(void) throw (EmptyCollectionException); 00114 00117 virtual const T& last(void) const throw (EmptyCollectionException); 00118 00121 void operator=(const CompleteBinaryTree<T> &tree); 00122 00123 private: 00124 unsigned int *_sizePtr, *_refCountPtr; 00125 DataPtr< BinTreeNode<T> > *_firstNodePtr, *_lastNodePtr; 00126 LinkedList< BinTreeNode<T> * > _parentList; 00127 }; // class BinaryTree 00128 00129 template <typename T> 00130 CompleteBinaryTree<T>::CompleteBinaryTree(void) 00131 : Collection<T>(), _parentList(LinkedList< BinTreeNode<T>* >()) 00132 { 00133 _sizePtr = new unsigned int; *_sizePtr = 0; 00134 _refCountPtr = new unsigned int; *_refCountPtr = 1; 00135 00136 _firstNodePtr = new DataPtr< BinTreeNode<T> >(); 00137 _lastNodePtr = new DataPtr< BinTreeNode<T> >(); 00138 00139 _firstNodePtr->data = NULL; 00140 _lastNodePtr->data = NULL; 00141 } 00142 00143 template <typename T> 00144 CompleteBinaryTree<T>::~CompleteBinaryTree(void) 00145 { 00146 if (*_refCountPtr > 1) 00147 (*_refCountPtr)--; 00148 else 00149 { 00150 // First destroy all the nodes! 00151 purge(); 00152 00153 delete _sizePtr; 00154 delete _refCountPtr; 00155 delete _firstNodePtr; 00156 delete _lastNodePtr; 00157 } 00158 } 00159 00160 template <typename T> 00161 void CompleteBinaryTree<T>::operator=(const CompleteBinaryTree<T> &t) 00162 { 00163 if (_refCountPtr == t._refCountPtr) 00164 return; 00165 00166 if (*_refCountPtr > 1) 00167 (*_refCountPtr)--; 00168 else 00169 { 00170 purge(); 00171 delete _sizePtr; delete _refCountPtr; 00172 delete _firstNodePtr; delete _lastNodePtr; 00173 } 00174 00175 _sizePtr = t._sizePtr; 00176 _refCountPtr = t._refCountPtr; 00177 _firstNodePtr = t._firstNodePtr; 00178 _lastNodePtr = t._lastNodePtr; 00179 _parentList = t._parentList; 00180 00181 (*_refCountPtr)++; 00182 } 00183 00184 template <typename T> 00185 CompleteBinaryTree<T>::CompleteBinaryTree(const CompleteBinaryTree<T> &bt) 00186 : Collection<T>(), 00187 _sizePtr(bt._sizePtr), 00188 _refCountPtr(bt._refCountPtr), 00189 _firstNodePtr(bt._firstNodePtr), 00190 _lastNodePtr(bt._lastNodePtr), 00191 _parentList(bt._parentList) 00192 { 00193 (*_refCountPtr)++; 00194 } 00195 00196 template <typename T> 00197 void CompleteBinaryTree<T>::pushBack(const T element) 00198 { 00199 BinTreeNode<T> *newNodePtr = new BinTreeNode<T>(); 00200 newNodePtr->data = element; 00201 00202 if (_lastNodePtr->data == NULL) 00203 { 00204 _lastNodePtr->data = newNodePtr; 00205 _firstNodePtr->data = newNodePtr; 00206 00207 _parentList.pushBack(newNodePtr); 00208 } 00209 else 00210 { 00211 BinTreeNode<T> *parentPtr = _parentList.first(); 00212 if (parentPtr->lchild == NULL) 00213 { 00214 parentPtr->lchild = newNodePtr; 00215 newNodePtr->parent = parentPtr; 00216 } 00217 else 00218 { 00219 parentPtr->rchild = newNodePtr; 00220 newNodePtr->parent = parentPtr; 00221 _parentList.popFront(); 00222 } 00223 00224 _parentList.pushBack(newNodePtr); 00225 _lastNodePtr->data = newNodePtr; 00226 } 00227 00228 (*_sizePtr)++; 00229 } // BinaryTree::pushBack 00230 00231 template <typename T> 00232 void CompleteBinaryTree<T>::popBack(void) 00233 { 00234 if (*_sizePtr == 0) 00235 return; 00236 00237 BinTreeNode<T> *nodePtr = _lastNodePtr->data; 00238 if (_parentList.size() != 0) 00239 _parentList.popBack(); 00240 00241 00242 if (nodePtr->parent == NULL) 00243 { 00244 _lastNodePtr->data = NULL; 00245 _firstNodePtr->data = NULL; 00246 } 00247 else if (nodePtr->parent->lchild == nodePtr) 00248 { 00249 nodePtr->parent->lchild = NULL; 00250 _lastNodePtr->data = _parentList.last(); 00251 } 00252 else 00253 { 00254 nodePtr->parent->rchild = NULL; 00255 _parentList.pushFront(nodePtr->parent); 00256 _lastNodePtr->data = _parentList.last(); 00257 } 00258 00259 00260 delete nodePtr; 00261 00262 (*_sizePtr)--; 00263 } // BinaryTree::popBack 00264 00265 template <typename T> 00266 void CompleteBinaryTree<T>::purge(void) 00267 { 00268 while (*_sizePtr != 0) 00269 popBack(); 00270 } // BinaryTree::purge 00271 00272 template <typename T> 00273 T& CompleteBinaryTree<T>::first(void) throw (EmptyCollectionException) 00274 { 00275 if (*_sizePtr == 0) 00276 throw EmptyCollectionException(); 00277 00278 return _firstNodePtr->data->data; 00279 } 00280 00281 template <typename T> 00282 const T& CompleteBinaryTree<T>::first(void) const throw (EmptyCollectionException) 00283 { 00284 if (*_sizePtr == 0) 00285 throw EmptyCollectionException(); 00286 00287 return _firstNodePtr->data->data; 00288 } 00289 00290 template <typename T> 00291 T& CompleteBinaryTree<T>::last(void) throw (EmptyCollectionException) 00292 { 00293 if (*_sizePtr == 0) 00294 throw EmptyCollectionException(); 00295 00296 return _lastNodePtr->data->data; 00297 } 00298 00299 template <typename T> 00300 const T& CompleteBinaryTree<T>::last(void) const throw (EmptyCollectionException) 00301 { 00302 if (*_sizePtr == 0) 00303 throw EmptyCollectionException(); 00304 00305 return _lastNodePtr->data->data; 00306 } 00307 00308 // ********************************************************************* 00309 // ********************************************************************* 00310 // ********************************************************************* 00311 00318 template <typename T> 00319 class BinTreeBreadthFirstIterator : public AbstractIterator<T> 00320 { 00321 00322 friend class CompleteBinaryTree<T>; 00323 00324 public: 00329 BinTreeBreadthFirstIterator(BinTreeNode<T> *rootNode); 00330 00333 virtual ~BinTreeBreadthFirstIterator() {} 00334 00337 virtual bool hasNext(void); 00338 00341 virtual T next(void) throw(OutOfBoundsException); 00342 00346 virtual void reset(void); 00347 00348 private: 00349 BinTreeNode<T> *_rootPtr; 00350 LinkedList< BinTreeNode<T> * > _nodeQ; 00351 }; // class BinTreeBreadthFirsthIterator 00352 00353 template <typename T> 00354 BinTreeBreadthFirstIterator<T>::BinTreeBreadthFirstIterator(BinTreeNode<T> *node) 00355 : _rootPtr(node), _nodeQ(LinkedList< BinTreeNode<T>* >()) 00356 { 00357 if (node != NULL) 00358 _nodeQ.pushBack(node); 00359 } 00360 00361 template <typename T> 00362 bool BinTreeBreadthFirstIterator<T>::hasNext(void) 00363 { 00364 if (_nodeQ.size() != 0) 00365 return true; 00366 else 00367 return false; 00368 } 00369 00370 template <typename T> 00371 T BinTreeBreadthFirstIterator<T>::next(void) throw(OutOfBoundsException) 00372 { 00373 if (_nodeQ.size() == 0) 00374 throw OutOfBoundsException(); 00375 00376 BinTreeNode<T> *nodePtr = _nodeQ.first(); 00377 if (nodePtr->lchild != NULL) 00378 _nodeQ.pushBack(nodePtr->lchild); 00379 if (nodePtr->rchild != NULL) 00380 _nodeQ.pushBack(nodePtr->rchild); 00381 00382 _nodeQ.popFront(); 00383 return nodePtr->data; 00384 } 00385 00386 template <typename T> 00387 void BinTreeBreadthFirstIterator<T>::reset(void) 00388 { 00389 _nodeQ.purge(); 00390 if (_rootPtr != NULL) 00391 _nodeQ.pushBack(_rootPtr); 00392 } 00393 00394 } // Namespace seal 00395 00396 #endif // __SEAL_BINTREE_H__ 00397