$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
tree.hh
1 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_UTIL_TREE_HH
27 # define MLN_UTIL_TREE_HH
28 
29 # include <vector>
30 # include <algorithm>
31 # include <iostream>
32 # include <algorithm>
33 # include <mln/core/contract.hh>
34 
42 namespace mln
43 {
44 
45  namespace util
46  {
47 
49  template <typename T> class tree_node;
50  template <typename T> class tree;
51  template <typename T> class branch;
52 
53 
57  template <typename T>
58  class tree_node
59  {
60  public:
61 
62  typedef std::vector< tree_node<T>* > children_t;
63 
67  tree_node();
68 
73  tree_node(T elt);
74 
75 
80  T& elt();
81 
86  const T& elt() const;
87 
88 
94 
95 
100  const children_t& children() const;
101 
102 
107  tree_node<T>* parent();
108 
109 
118 
127 
135 
140 
148  void print(std::ostream& ostr, int level = 0);
149 
154  bool check_consistency();
155 
156 
164  tree_node<T>* search(T& elt);
165 
167  int search_rec(tree_node<T>** res, T& elt);
168 
169  private:
170 
172  T elt_;
173 
175  tree_node<T>* parent_;
176 
178  std::vector< tree_node<T>* > child_;
179  };
180 
181 
182 
186  template <typename T>
187  class tree
188  {
189  public:
190 
192 
196  tree();
197 
203 
204 
209  tree_node<T>* root();
210 
216 
221  bool check_consistency();
222 
223 
229  void add_tree_up (T& elt);
230 
236  void add_tree_down (T& elt);
237 
238  private:
239 
241  tree_node<T>* root_;
242  };
243 
244 
248  template <typename T>
249  class branch
250  {
251  public:
252 
259 
264  tree_node<T>& apex();
265 
270  tree<T>& util_tree();
271 
272  private:
274  util::tree<T>& tree_;
275 
277  tree_node<T>& apex_;
278  };
279 
280 
281 # ifndef MLN_INCLUDE_ONLY
282 
283  template <typename T>
284  inline
285  tree<T>::tree()
286  : root_ (0)
287  {
288  }
289 
290  template <typename T>
291  inline
292  tree<T>::tree(tree_node<T>* root)
293  : root_ (root)
294  {
295  mln_assertion (root != 0);
296  }
297 
298  template <typename T>
299  inline
300  tree_node<T>*
301  tree<T>::root()
302  {
303  return root_;
304  }
305 
306  template <typename T>
307  inline
308  branch<T>
310  {
311  return branch<T>(*this, *root());
312  }
313 
314  template <typename T>
315  inline
316  void
317  tree<T>::add_tree_up(T& elt)
318  {
319  tree_node<T>* n = new tree_node<T> (elt);
320  root_->set_parent(n);
321  n->children().push_back (root_);
322  root_ = n;
323  }
324 
325  template <typename T>
326  inline
327  void
329  {
330  tree_node<T>* n = new tree_node<T> (elt);
331  root_->child_.push_back (n);
332  }
333 
334 
335  template <typename T>
336  inline
337  bool
339  {
340  return root()->check_consistency ();
341  }
342 
343  template <typename T>
344  inline
346  : parent_ (0)
347  {
348  }
349 
350  template <typename T>
351  inline
353  : elt_ (elt),
354  parent_ (0)
355  {
356  }
357 
358  template <typename T>
359  inline
360  const T&
361  tree_node<T>::elt() const
362  {
363  return elt_;
364  }
365 
366  template <typename T>
367  inline
368  T&
370  {
371  return elt_;
372  }
373 
374 
375  template <typename T>
376  inline
377  std::vector< tree_node<T>* >&
379  {
380  return child_;
381  }
382 
383  template <typename T>
384  inline
385  const std::vector< tree_node<T>* >&
386  tree_node<T>::children() const
387  {
388  return child_;
389  }
390 
391  template <typename T>
392  inline
393  tree_node<T>*
395  {
396  tree_node<T>* s = new tree_node<T>(elt);
397 
398  s->parent_ = this;
399  this->child_.push_back(s);
400  return s;
401  }
402 
403 
404  template <typename T>
405  inline
406  tree_node<T>*
407  tree_node<T>::add_child(tree_node<T>* tree_node)
408  {
409  if (tree_node->parent_)
410  {
411  for (typename std::vector<util::tree_node<T>* >::iterator it = tree_node->parent()->children().begin();
412  it != tree_node->parent()->children().end(); ++it)
413  if ((*it) == tree_node)
414  {
415  tree_node->parent()->children().erase(it);
416  break;
417  }
418  }
419  tree_node->parent_ = this;
420  this->children().push_back(tree_node);
421  return tree_node;
422  }
423 
424  template <typename T>
425  inline
426  tree_node<T>*
428  {
429  mln_assertion(parent_ != 0);
430  tree_node<T>* res = parent_;
431 
432  typename std::vector<tree_node<T>* >::iterator it = parent_->children().begin();
433  for (; it < parent_->children().end(); ++it)
434  if ((*it) == this)
435  {
436  parent_->children().erase(it);
437  break;
438  }
439 
440  for (typename std::vector<tree_node<T>* >::iterator it = this->child_.begin();
441  it != this->child_.end(); ++it)
442  parent_->add_child(*it);
443  return (res);
444  }
445 
446  template <typename T>
447  inline
448  void
449  tree_node<T>::print(std::ostream& ostr, int level)
450  {
451  ostr << level << std::endl;
452 
453  ostr << " elt " << this->elt() << std::endl;
454 
455 
456  for (typename std::vector<tree_node<T>* >::iterator it = this->child_.begin();
457  it != this->child_.end(); ++it)
458  {
459  (*it)->print(level + 1);
460  }
461  }
462 
463 
464  template <typename T>
465  inline
466  void
467  tree_node<T>::set_parent(tree_node<T>* parent)
468  {
469  mln_assertion(parent != 0);
470  parent_ = parent;
471  parent->child_.push_back(this);
472  }
473 
474  template <typename T>
475  inline
476  tree_node<T>*
478  {
479  return parent_;
480  }
481 
482  template <typename T>
483  inline
484  int
485  tree_node<T>::search_rec(tree_node<T>** res, T& elt)
486  {
487  if (elt == this->elt_)
488  {
489  *res = this;
490  return 1;
491  }
492  else
493  {
494  for (typename std::vector<tree_node<T>* >::iterator it = this->child_.begin();
495  it != this->child_.end(); ++it)
496  {
497  if ((**it).search_rec(res, elt))
498  return 1;
499  }
500  }
501  return 0;
502  }
503 
504  template <typename T>
505  inline
506  tree_node<T>*
507  tree_node<T>::search(T& elt)
508  {
509  tree_node<T>* res = 0;
510 
511  if (search_rec(&res, elt))
512  return res;
513  return 0;
514  }
515 
516  template <typename T>
517  inline
518  bool
520  {
521  for (typename std::vector<tree_node<T>* >::iterator it = this->child_.begin();
522  it != this->child_.end(); ++it)
523  {
524  if ((**it).parent() != this)
525  return false;
526 
527  if (!((**it).check_consistency()))
528  return false;
529  }
530  return true;
531  }
532 
533 
534  // Branch methods
535  template <typename T>
536  inline
537  branch<T>::branch(util::tree<T>& tree,
538  util::tree_node<T>& apex)
539  : tree_(tree),
540  apex_(apex)
541  {
542  }
543 
544 
545  template <typename T>
546  inline
547  util::tree_node<T>&
549  {
550  return apex_;
551  }
552 
553  template <typename T>
554  inline
557  {
558  return tree_;
559  }
560 
561 # endif // ! MLN_INCLUDE_ONLY
562 
563  } // end of namespace mln::util
564 
565 
566 } // end of namespace mln
567 
568 
569 #endif // ! MLN_UTIL_TREE_HH