Add level traversal

This commit is contained in:
Simon Giraudot 2021-02-03 08:26:03 +01:00
parent 5aeb07d654
commit c15327a901
2 changed files with 81 additions and 1 deletions

View File

@ -12,6 +12,7 @@
\cgalHasModel `CGAL::Orthtrees::Preorder_traversal` \cgalHasModel `CGAL::Orthtrees::Preorder_traversal`
\cgalHasModel `CGAL::Orthtrees::Postorder_traversal` \cgalHasModel `CGAL::Orthtrees::Postorder_traversal`
\cgalHasModel `CGAL::Orthtrees::Leaves_traversal` \cgalHasModel `CGAL::Orthtrees::Leaves_traversal`
\cgalHasModel `CGAL::Orthtrees::Level_traversal`
*/ */
class OrthtreeTraversal { class OrthtreeTraversal {

View File

@ -18,6 +18,8 @@
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include <CGAL/Orthtree/Traversal_iterator.h> #include <CGAL/Orthtree/Traversal_iterator.h>
#include <stack>
namespace CGAL { namespace CGAL {
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
@ -85,6 +87,34 @@ Node deepest_first_child(Node n) {
return first; return first;
} }
template <typename Node>
Node first_child_at_depth(Node n, std::size_t depth) {
if (n.is_null())
return Node();
std::stack<Node> todo;
todo.push(n);
if (n.depth() == depth)
return n;
while (!todo.empty())
{
Node node = todo.top();
todo.pop();
if (node.depth() == depth)
return node;
if (!node.is_leaf())
for (std::size_t i = 0; i < Node::Degree::value; ++ i)
todo.push(node[Node::Degree::value - 1 - i]);
}
return Node();
}
/// \endcond /// \endcond
/*! /*!
@ -141,7 +171,7 @@ struct Postorder_traversal {
Node next = deepest_first_child(next_sibling(n)); Node next = deepest_first_child(next_sibling(n));
if (!next) if (next.is_null())
next = n.parent(); next = n.parent();
return next; return next;
@ -176,6 +206,55 @@ struct Leaves_traversal {
} }
}; };
/*!
\ingroup PkgOrthtreeTraversal
\brief A class used for performing a traversal of a specific depth level.
All trees at another depth are ignored. If the selected depth is
higher than the maximum depth of the orthtree, no node will be traversed.
\cgalModels OrthtreeTraversal
*/
struct Level_traversal {
private:
const std::size_t depth;
public:
/*!
constructs a `depth`-level traversal.
*/
Level_traversal (std::size_t depth) : depth(depth) { }
template <typename Node>
Node first(Node root) const {
return first_child_at_depth(root, depth);
}
template <typename Node>
Node next(Node n) const {
std::cerr << depth << " ";
Node next = next_sibling(n);
if (next.is_null())
{
Node up = n;
do
{
up = next_sibling_up(up);
if (up.is_null())
return Node();
next = first_child_at_depth(up, depth);
}
while (next.is_null());
}
return next;
}
};
} // Orthtree } // Orthtree
} // CGAL } // CGAL