kpeeters / tree.hh

An STL-like C++ header-only tree library
GNU General Public License v3.0
132 stars 31 forks source link

Iterative tree creation #16

Closed TMueller83 closed 3 months ago

TMueller83 commented 2 years ago

Hi,

I try to create a tree in an iterative way: I start with one head node and then make a loop for the depth of the tree. In each iteration I want to add child nodes to the leafs of the tree. My current approach is as follows:

#include "tree.h"

int main(){

  // Initialize the tree
  tree<int> tr = tree<int>(1);

  // Loop for the depth of the tree
  int node_counter = 1;
  for (int depth = 1; depth <= 3; ++depth)
  {
    // Iterate over the leaf nodes
    tree<int>::leaf_iterator leaf_node = tr.begin_leaf();
    while(leaf_node != tr.end_leaf())
    {
      // Add children to the leaf node
      for (int k = 1; k <= 3; ++k)
      {
        tr.append_child(leaf_node, node_counter);
        ++node_counter;
      }
      // Go to the next leaf node
      ++leaf_node;
    }
  }

  return 0;
}

However, the while-loop over the leaf nodes never terminates. Is this because I change the tree on the flight or is it a bug? If it is not a bug, how can one create a tree in an iterative way?

kpeeters commented 3 months ago

Yes, leaf iterators will descend into the newly created subtree if you do things as above. To avoid this, make a copy of the leaf iterator and increment that before you append to the tree. E.g.

int main()
   {
   // Initialize the tree
   tree<int> tr = tree<int>(1);

   // Loop for the depth of the tree
   int node_counter = 1;
   for (int depth = 1; depth <= 3; ++depth) {
      // Iterate over the leaf nodes
      tree<int>::leaf_iterator leaf_node = tr.begin_leaf();
      while(leaf_node != tr.end_leaf()) {
         auto next_leaf=leaf_node;
         ++next_leaf;
         // Add children to the leaf node
         for (int k = 1; k <= 3; ++k) {
            tr.append_child(leaf_node, node_counter);
            ++node_counter;
            }
         // Go to the next leaf node
         leaf_node = next_leaf;
         }
      }
   return 0;
   }