tree.h

Go to the documentation of this file.
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 TREE_TREE_H
00009 #define TREE_TREE_H
00010 
00011 #include <list>
00012 #include <stack>
00013 #include <ext/hash_map>
00014 #include "tree/tree-node.h"
00015 
00016 using namespace std;
00017 using namespace __gnu_cxx;
00018 
00019 namespace libpmk {
00020 
00021 // TODO: clarify behavior when tree is empty.
00022 // Tree always has a root with ID 0.
00023 
00026 
00064 template <class T>
00065 class Tree {
00066 public:
00067   Tree();
00068   ~Tree();
00069 
00072   Tree(const Tree<T>& other);
00073 
00074   class Iterator;
00075   class PreorderIterator;
00076   class PostorderIterator;
00077   class BreadthFirstIterator;
00078 
00080   void clear();
00081 
00083   T* root() { return tree_[0]; }
00084   const T* root() const { return node(0); }
00085 
00087   int size() const { return tree_.size(); }
00088 
00090 
00093   T* node(int id);
00094   const T* node(int id) const;
00095 
00097 
00121   T* add_node(const T& new_node);
00122 
00124 
00131   T* add_node();
00132 
00133 
00135 
00143   void ReadFromStream(istream& input_stream);
00144 
00146 
00150   void WriteToStream(ostream& output_stream) const;
00151 
00152 
00154   void DeleteNode(int node_id);
00155 
00157   PreorderIterator BeginPreorder() const;
00158 
00160   const PreorderIterator& EndPreorder() const;
00161 
00163   PostorderIterator BeginPostorder() const;
00164 
00166   const PostorderIterator& EndPostorder() const;
00167 
00169   BreadthFirstIterator BeginBreadthFirst() const;
00170 
00172   const BreadthFirstIterator& EndBreadthFirst() const;
00173 
00175   class Iterator {
00176   public:
00178     Iterator(int node_id, const Tree<T>* source_tree) :
00179       node_id_(node_id), source_tree_(source_tree) { }
00180 
00181     virtual ~Iterator() { }
00182 
00184     Iterator& operator=(const Iterator& other) {
00185       node_id_ = other.node_id_;
00186       return *this;
00187     }
00188 
00190     bool operator==(const Iterator& other) {
00191       return node_id_ == other.node_id_;
00192     }
00193 
00195     bool operator!=(const Iterator& other) {
00196       return node_id_ != other.node_id_;
00197     }
00198 
00199     int operator*() {
00200       return node_id_;
00201     }
00202 
00203     int id() {
00204       return node_id_;
00205     }
00206 
00207     virtual Iterator& operator++() = 0;
00208 
00209   protected:
00210     int node_id_;
00211     const Tree<T>* source_tree_;
00212   };
00213 
00214 
00215   // Internally, we let <node_id_> be the current position. <todo_>
00216   // contains the IDs of all remaining nodes, but the nodes in <todo_>
00217   // may have yet to be expanded.
00219   class PreorderIterator : public Iterator {
00220   public:
00223     PreorderIterator(int node_id, const Tree<T>* tree) :
00224       Iterator(node_id, tree) { }
00225     virtual ~PreorderIterator() {}
00226     virtual Iterator& operator++();
00227 
00228   private:
00229     list<int> todo_;
00230   };
00231 
00232   class PostorderIterator : public Iterator {
00233   public:
00236     PostorderIterator(int node_id, const Tree<T>* tree);
00237     virtual ~PostorderIterator() {}
00238     virtual Iterator& operator++();
00239 
00240   private:
00241     stack<int> todo_;
00242     stack<bool> visited_;
00243   };
00244 
00246   class BreadthFirstIterator : public Iterator {
00247   public:
00250     BreadthFirstIterator(int node_id, const Tree<T>* tree) :
00251       Iterator(node_id, tree) {}
00252     virtual ~BreadthFirstIterator() {}
00253     virtual Iterator& operator++();
00254   private:
00255     list<int> todo_;
00256   };
00257 
00258 private:
00259   hash_map<int, T*> tree_;
00260   int last_used_id_;
00261 
00262   // Block the copy assignment operator
00263   void operator=(const Tree<T>&);
00264 
00265   // Pre-create some end-iterators so we don't have to always create
00266   // them. This is useful for loops like:
00267   //   while (iter != tree.EndPreorder())
00268   // because calling this iterators generally involves instantiating
00269   // an STL stack, vector, or list.
00270   const PreorderIterator end_preorder_;
00271   const PostorderIterator end_postorder_;
00272   const BreadthFirstIterator end_breadth_first_;
00273 };
00274 }  // namespace libpmk
00275 
00276 #endif  // TREE_TREE_H

Generated on Fri Sep 21 11:39:04 2007 for libpmk2 by  doxygen 1.5.1