views:

59

answers:

1

I have a tree of objects, where each object has a std::vector of pointers to its children. The class of the object has a rewrite() method that is recursively applied to alter the object and its children, typically with the following transformations, where [N] is the object being rewritten and (M) is the element that rewrite() returns:

                 (A)
 [A]             / \               [A]
 / \     -->    B   X               |    -->    (B)
B   C                \              B
                      C

What's the cleanest way of extending this setup to allow transformations like this?

    A             X
    |            / \
   [B]   -->    C   A
    |               |
    C              (Y)

That is, those that re-root the tree, move an element, insert a new element, and return the inserted element. I'm having a hard time coming up with something nice that also involves minimal refactoring. Thoughts?

+1  A: 

Looks like, for speed, you'll need a "back-pointer" from each child node to its parent node. This way you can follow the chain of parent pointers given a pointer to any node all the way to the root, if that's what you need (I'm not sure how else you planned to find the root given just a pointer to an inner node, without backpointers?). Of course, you'll need to adjust the back pointer, as well as the "children" std::vector, whenever you rearrange the tree -- an unfortunate consequence of the slight duplication of information (no more than, say, a doubly linked list presents;-), but a small price to pay for the ease and speed of such bidirectional navigation.

Alex Martelli
I solved it by passing a reference to the root pointer as a parameter to `rewrite()`. Rewrites can now alter the root however they please. Thanks for the tip, anyway: it put me on the right track.
Jon Purdy