00001 // Copyright 2007, Massachusetts Institute of Technology. 00002 // The use of this code is permitted for research only. There is 00003 // absolutely no warranty for this software. 00004 // 00005 // Author: John Lee (jjl@mit.edu) 00006 // 00007 00008 #ifndef UTIL_TREE_H 00009 #define UTIL_TREE_H 00010 00011 #include <list> 00012 #include <stack> 00013 #include "util/tree-node.h" 00014 00015 using namespace std; 00016 00017 namespace libpmk { 00018 00021 00078 template <class T> 00079 class Tree { 00080 public: 00081 Tree(); 00082 ~Tree(); 00083 00085 Tree(const Tree<T>& other); 00086 Tree(const Tree<T>& one, const Tree<T>& two); 00087 00088 class Iterator; 00089 class PreorderIterator; 00090 class PostorderIterator; 00091 class BreadthFirstIterator; 00092 00094 T* const GetRootNode() const; 00095 00097 int GetNumNodes() const; 00098 00100 T* GetNode(const LargeIndex& index); 00101 00103 00106 T* GetNode(const LargeIndex& index, TreeNode* finger); 00107 00109 00114 T* GetRootNode(); 00115 00117 00134 T* AddNode(const T& new_node); 00135 00137 00143 T* AddNode(const T& new_node, TreeNode* parent); 00144 00146 00158 void ReadFromStream(istream& input_stream); 00159 00161 00165 void WriteToStream(ostream& output_stream) const; 00166 00167 00169 00173 void DeleteNode(TreeNode* node); 00174 00176 PreorderIterator BeginPreorder() const; 00177 00179 static const PreorderIterator& EndPreorder(); 00180 00182 PostorderIterator BeginPostorder() const; 00183 00185 static const PostorderIterator& EndPostorder(); 00186 00188 BreadthFirstIterator BeginBreadthFirst() const; 00189 00191 static const BreadthFirstIterator& EndBreadthFirst(); 00192 00194 class Iterator { 00195 public: 00197 Iterator(TreeNode* node) : node_(node) {} 00198 virtual ~Iterator() {} 00199 00201 Iterator& operator=(const Iterator& other) { 00202 node_ = other.node_; 00203 return *this; 00204 } 00205 00207 bool operator==(const Iterator& other) { 00208 return node_ == other.node_; 00209 } 00210 00212 bool operator!=(const Iterator& other) { 00213 return node_ != other.node_; 00214 } 00215 00217 T* operator->() { 00218 return static_cast<T*>(node_); 00219 } 00220 00222 T* get() { 00223 return static_cast<T*>(node_); 00224 } 00225 virtual Iterator& operator++() = 0; 00226 00227 protected: 00228 TreeNode* node_; 00229 }; 00230 00231 00232 // Internally, we let <node_> be the current position. <todo_> 00233 // contains all remaining nodes, but the nodes in <todo_> may 00234 // have yet to be expanded. 00236 class PreorderIterator : public Iterator { 00237 public: 00240 PreorderIterator(T* node) : Iterator(node) {} 00241 virtual ~PreorderIterator() {} 00242 virtual Iterator& operator++(); 00243 00244 private: 00245 list<TreeNode*> todo_; 00246 }; 00247 00248 00249 class PostorderIterator : public Iterator { 00250 public: 00253 PostorderIterator(T* node); 00254 virtual ~PostorderIterator() {} 00255 virtual Iterator& operator++(); 00256 00257 private: 00258 stack<TreeNode*> todo_; 00259 stack<bool> visited_; 00260 }; 00261 00263 class BreadthFirstIterator : public Iterator { 00264 public: 00267 BreadthFirstIterator(T* node) : Iterator(node) {} 00268 virtual ~BreadthFirstIterator() {} 00269 virtual Iterator& operator++(); 00270 private: 00271 list<TreeNode*> todo_; 00272 }; 00273 00274 private: 00275 T* root_node_; 00276 void DeleteLeafNode(TreeNode* node); 00277 void FreeAllNodes(); 00278 00279 // Assumes my_node has no children (will not free any memory). 00280 // Makes my_node's children into a deep copy of other_node (copies 00281 // children and link structure as well). This will increment the 00282 // node count for each new bin added as well. It will NOT modify 00283 // my_node however. 00284 void CopySubtree(T** my_node, T* other_node); 00285 int num_nodes_; 00286 00287 // Block the copy assignment operator 00288 void operator=(const Tree<T>&); 00289 00290 // Static variable hacks so we don't have to always create end-iterators. 00291 static PreorderIterator end_preorder_; 00292 static PostorderIterator end_postorder_; 00293 static BreadthFirstIterator end_breadth_first_; 00294 }; 00295 } // namespace libpmk 00296 #endif // UTIL_TREE_H