Tree.cpp

Go to the documentation of this file.
00001 
00021 // Mint headers
00022 #include "Tree.hpp"
00023 
00024 namespace OA {
00025 
00026 template <class T> void deque_erase (std::deque<T> d, T elt);
00027 
00028 //--------------------------------------------------------------------
00033 Tree::OutEdgesIterator::OutEdgesIterator (const Node&  n)
00034 {
00035   mQueue = n.outgoing;
00036   mIter = mQueue->begin();
00037   OA_ptr<Edge>  e; e = 0;
00038   if (mIter != mQueue->end()) {
00039     e = *mIter;
00040   }
00041   while ((e.ptrEqual(0)) && (mIter != mQueue->end())) {
00042     ++mIter;
00043     e = *mIter;
00044   }
00045 }
00046 //--------------------------------------------------------------------
00047 
00048 //--------------------------------------------------------------------
00050 void
00051 Tree::OutEdgesIterator::operator ++ ()
00052 {
00053   ++mIter;
00054   OA_ptr<Edge>  e; e = 0;
00055   if (mIter != mQueue->end())
00056     e = *mIter;
00057   while ((e.ptrEqual(0)) && (mIter != mQueue->end())) {
00058     ++mIter;
00059     e = *mIter;
00060   }
00061 }
00062 //--------------------------------------------------------------------
00063 
00064 
00065 //--------------------------------------------------------------------
00073 Tree::PreOrderIterator::PreOrderIterator (Tree& t)
00074 {
00075   if (! t.root_node.ptrEqual(0)) {
00076     if (t.preorder_needed) {
00077       // reset all the preoder_next links
00078       std::set<OA_ptr<Node> >::iterator ni = t.node_set->begin();
00079       while (ni != t.node_set->end()) {
00080         OA_ptr<Node>  n = *ni;
00081         n->next_preorder = 0;
00082         ++ni;
00083       }
00084       t.create_preorder_links(t.root_node);
00085       t.preorder_needed = false;
00086     }
00087   }
00088   p = t.root_node;
00089 }
00090 //--------------------------------------------------------------------
00091 
00092 
00093 //--------------------------------------------------------------------
00099 OA_ptr<Tree::Node> 
00100 Tree::create_preorder_links (OA_ptr<Tree::Node>  n)
00101 {
00102   OA_ptr<Node>  last;
00103 
00104   ChildNodesIterator iter(*n);
00105   if (!iter.isValid()) {
00106     n->next_preorder = 0;
00107     last = n;
00108   }
00109   else {
00110     last = n;
00111     do {
00112       last->next_preorder = iter.current();
00113       last = create_preorder_links(iter.current());
00114       ++iter;
00115     } while (iter.isValid());
00116   }
00117   return last;
00118 }
00119 //--------------------------------------------------------------------
00120 
00121 //--------------------------------------------------------------------
00129 Tree::PostOrderIterator::PostOrderIterator (Tree& t)
00130 {
00131   if (! t.root_node.ptrEqual(0)) {
00132     if (t.postorder_needed) {
00133       // reset all the preoder_next links
00134       std::set<OA_ptr<Node> >::iterator ni = t.node_set->begin();
00135       while (ni != t.node_set->end()) {
00136         OA_ptr<Node>  n = *ni;
00137         n->next_postorder = NULL;
00138         n->prev_postorder = NULL;
00139         ++ni;
00140       }
00141       OA_ptr<Node> nullNode;  nullNode = NULL;
00142       t.create_postorder_links(t.root_node, nullNode);
00143       t.postorder_needed = false;
00144       t.rpostorder_needed = false;
00145     }
00146   }
00147   p = t.mPostOrderStart;
00148 }
00149 //--------------------------------------------------------------------
00150 
00151 
00152 //--------------------------------------------------------------------
00158 OA_ptr<Tree::Node> 
00159 Tree::create_postorder_links (OA_ptr<Tree::Node>  n, OA_ptr<Tree::Node> last)
00160 {
00161   OA_ptr<Node> retLast = last;
00162 
00163   ChildNodesIterator iter(*n);
00164   for (; iter.isValid(); ++iter) {
00165     retLast = create_postorder_links(iter.current(),retLast);
00166   }
00167  
00168   // links for this node
00169   if (retLast.ptrEqual(NULL)) { // this is the first node in postorder
00170     mPostOrderStart = n;
00171   } else {
00172     retLast->next_postorder = n;
00173   }
00174   n->prev_postorder = retLast;
00175   retLast = n;
00176 
00177   return retLast;
00178 }
00179 //--------------------------------------------------------------------
00180 
00181 
00182 //--------------------------------------------------------------------
00185 void
00186 Tree::addEdge(OA_ptr<Tree::Edge>  e)
00187   throw (Tree::DuplicateEdge, Tree::EdgeInUse, Tree::EmptyEdge, Tree::SecondParent, Tree::EmptyEndPoint)
00188 {
00189   if (e.ptrEqual(0)) {
00190     throw EmptyEdge();
00191   }
00192   if (edge_set->find(e) != edge_set->end()) {
00193     throw DuplicateEdge(e);
00194   }
00195   if (e->in_use) {
00196     throw EdgeInUse(e);
00197   }
00198   if ((e->child_node.ptrEqual(0)) || (e->parent_node.ptrEqual(0))) {
00199     throw EmptyEndPoint(e);
00200   }
00201   if (!e->child_node->incoming.ptrEqual(0)) {
00202       throw SecondParent(e);
00203   }
00204 
00205   // insert the nodes if they don't already exist in the graph
00206   if (node_set->find(e->parent_node) == node_set->end()) {
00207     addNode(e->parent_node);
00208   }
00209   if (node_set->find(e->child_node) == node_set->end()) {
00210     addNode(e->child_node);
00211   }
00212 
00213   // insert the edge in the corresponding lists of the two nodes
00214   e->parent_node->outgoing->push_back(e);
00215   e->child_node->incoming = e;
00216 
00217   // finally, insert the edge itself in the tree
00218   e->in_use = true;
00219   edge_set->insert(e);
00220   preorder_needed = postorder_needed = rpostorder_needed = true;
00221 }
00222 //--------------------------------------------------------------------
00223 
00224 
00225 //--------------------------------------------------------------------
00227 void
00228 Tree::addNode(OA_ptr<Tree::Node>  n)
00229   throw (Tree::DuplicateNode, Tree::NodeInUse, Tree::EmptyNode)
00230 {
00231   if (n.ptrEqual(0)) {
00232     throw EmptyNode();
00233   }
00234   if (node_set->find(n) != node_set->end()) {
00235     throw DuplicateNode(n);
00236   }
00237   if (n->in_use) {
00238     throw NodeInUse(n);
00239   }
00240   if (root_node.ptrEqual(0)) {
00241     root_node = n;
00242   }
00243   n->in_use = true;
00244   node_set->insert(n);
00245   preorder_needed = postorder_needed = rpostorder_needed = true;
00246 }
00247 //--------------------------------------------------------------------
00248 
00249 
00250 //--------------------------------------------------------------------
00254 void
00255 Tree::add_empty_edge (OA_ptr<Tree::Node> n)
00256   throw (Tree::EmptyNode)
00257 {
00258   if (n.ptrEqual(0)) {
00259     throw EmptyNode();
00260   }
00261   OA_ptr<Edge> nullEdge; nullEdge = 0;
00262   n->outgoing->push_back(nullEdge);
00263 }
00264 //--------------------------------------------------------------------
00265 
00266 
00267 //--------------------------------------------------------------------
00268 void
00269 Tree::removeEdge (OA_ptr<Tree::Edge>  e)
00270   throw (Tree::NonexistentEdge, Tree::EmptyEdge)
00271 {
00272   if (e.ptrEqual(0)) {
00273     throw EmptyEdge();
00274   }
00275   if (edge_set->erase(e) == 0) {
00276     throw NonexistentEdge(e);
00277   }
00278   preorder_needed = postorder_needed = rpostorder_needed = true;
00279   e->in_use = false;
00280   deque_erase<OA_ptr<Edge> >(*(e->parent_node->outgoing), e);
00281   e->child_node->incoming = 0;
00282 }
00283 //--------------------------------------------------------------------
00284 
00285 
00286 //--------------------------------------------------------------------
00287 void
00288 Tree::removeNode (OA_ptr<Tree::Node>  n)
00289   throw (Tree::NonexistentNode, Tree::DeletingRootOfNonSingletonTree, Tree::EmptyNode)
00290 {
00291   if (n.ptrEqual(0)) {
00292     throw EmptyNode();
00293   }
00294   if ((n.ptrEqual(root_node)) && (!edge_set->empty() || (node_set->size() > 1)))
00295     throw DeletingRootOfNonSingletonTree(n);
00296   if (node_set->erase(n) == 0)
00297     throw NonexistentNode(n);
00298   preorder_needed = postorder_needed = rpostorder_needed = true;
00299   n->in_use = false;
00300   if (n == root_node)
00301     root_node = 0;
00302 
00303   if (! n->incoming.ptrEqual(0)) {
00304     edge_set->erase(n->incoming);
00305     deque_erase<OA_ptr<Edge> >(*(n->incoming->parent_node->outgoing), 
00306                                n->incoming);
00307   }
00308 
00309   OutEdgesIterator out(*n);
00310   while (out.isValid()) {
00311     OA_ptr<Edge>  e = out.current();
00312     e->child_node->incoming = 0;
00313     edge_set->erase(e);
00314     ++out;
00315   }
00316 }
00317 //--------------------------------------------------------------------------------------------------------------------
00318 
00319 
00320 //--------------------------------------------------------------------
00323 template <class T>
00324 void
00325 deque_erase (std::deque<T> d, T elt)
00326 {
00327   typename std::deque<T>::iterator iter = d.begin();
00328   while (iter != d.end()) {
00329     T k = *iter;
00330     if (k == elt) {
00331       d.erase(iter);
00332       break;
00333     }
00334   }
00335 }
00336 //--------------------------------------------------------------------------------------------------------------------
00337 
00338 
00339 //--------------------------------------------------------------------------------------------------------------------
00345 /*
00346 OA_ptr<Tree::Node>
00347 Tree::clone (OA_ptr<Tree::Node>  subtree)
00348 {
00349   OA_ptr<Node>  new_root = subtree->new_copy();
00350   OutEdgesIterator edge_iter(*subtree);
00351   while (edge_iter.isValid()) {
00352     OA_ptr<Edge>  out_edge = edge_iter.current();
00353     if (! out_edge.ptrEqual(0)) {
00354       OA_ptr<Node>  new_child = clone(out_edge->sink());
00355       addEdge(out_edge->new_copy(new_root, new_child));
00356     }
00357     else {
00358       OA_ptr<Edge> nullEdge; nullEdge = 0;
00359       new_root->outgoing->push_back(nullEdge);
00360     }
00361     ++edge_iter;
00362   }
00363   return new_root;
00364 }
00365 */
00366 //--------------------------------------------------------------------------------------------------------------------
00367 
00368 } // end of OA namespace

Generated on Fri Nov 7 05:21:53 2008 for OpenAnalysis by  doxygen 1.5.5