Search code examples
c++treeparent-childchildrenappendchild

Move an arbitrary node and its children as child in tree.hh


I am using the tree.hh implementation. I have a simple "tree" like the following (A, B and C are siblings without parents, B1 is child to B):

A
B
  B1
C

Now I want to "move" C to be also a child of B. I tried the following minimal example, but did not find a easy way to do this using the methods in tree.hh.

The only solution I found was:

  1. Extract a subtree from C and its children (which removes it from the original tree)
  2. Append the subtree of C as child to the desired new parent B

See code on pastebin.com

#include <iostream>
#include "tree.hh"
#include "tree_util.hh"

void print_tree(const tree<std::string>& tr)
{
    tree<std::string>::pre_order_iterator it = tr.begin();
    tree<std::string>::pre_order_iterator end = tr.end();
    if(!tr.is_valid(it)) return;
    int rootdepth=tr.depth(it);
    std::cout << "-----" << std::endl;
    while(it!=end) {
        for(int i=0; i<tr.depth(it)-rootdepth; ++i)
            std::cout << "  ";
        std::cout << (*it) << std::endl << std::flush;
        ++it;
        }
    std::cout << "-----" << std::endl;
}

int main(int, char **)
{
    tree<std::string> my_tree;

    tree<std::string>::iterator iA = my_tree.insert(my_tree.end(), "A");
    tree<std::string>::iterator iB = my_tree.insert(my_tree.end(), "B");
    tree<std::string>::iterator iB1 = my_tree.append_child(iB, "B1");
    tree<std::string>::iterator iC = my_tree.insert(my_tree.end(), "C");        
    print_tree(my_tree);

    // this makes a copy of "C" --> not what I want
    auto iC_append = my_tree.append_child(iB, iC);
    print_tree(my_tree);
    my_tree.erase(iC_append);

    // this extracts "C" into a separate tree and then appends the tree as child to "B"
    tree<std::string> sub_tree = my_tree.move_out(iC);
    my_tree.move_in_as_nth_child(iB, my_tree.number_of_children(iB), sub_tree);
    print_tree(my_tree);
}

I doubt, that this is the most simple solution possible. Any ideas what I am doing wrong?

Thanks!

Cheers, Jonathan


Solution

  • Use move_after, as in

    my_tree.move_after(iB1, iC);
    

    This moves the node at iC (and any children, if present) to become a sibling of B.