So you want to create a full binary tree of a specified depth using a loop.
That`s possible. But you should really consider @PaulColdrey`s answer first, as it is quite a bit simpler.
To create a binary tree iteratively, one has to know that its every node can be uniquely identified with a bit vector:
layer 0: ___________________[0]___________________
| |
layer 1: ________[00]________ ________[10]________
| | | |
layer 2: ___[000]___ ___[100]___ ___[010]___ ___[110]___
| | | | | | | |
layer 3: [0000] [1000] [0100] [1100] [0010] [1010] [0110] [1110]
A bit on Nth position tells which branch (left: 0 / right: 1) has been taken when going from (N – 1)th layer to Nth. In other words, a bit vector is a path to the node; see above.
It is sufficient to count from 0 to 2K – 1 to get all possible paths to Kth layer nodes. And on top of that, when counting up, Nth bit would never change from 0 to 1 until all less significant bits change from 0 to 1 — which in this case means that the current Nth layer subtree is full.
This allows to only remember one current node per layer, recreating all children when a parent node changes.
This is how it looks in C:
struct NODE {
struct NODE *side[2];
double data;
};
struct NODE *fulltree(int depth) {
struct NODE *curr[16] = {};
int path, layer;
if ((depth >= 0) && (depth < 16)) { /** reject exceedingly large trees **/
curr[0] = (struct NODE*)calloc(1, sizeof(struct NODE));
for (path = 0; path < (1 << depth); ++path)
for (layer = 1; layer <= depth; ++layer)
if (((path ^ (path - 1)) >> (depth - layer)) & 1) {
curr[layer - 1]->side[(path >> (depth - layer)) & 1] =
curr[layer] = (struct NODE*)calloc(1, sizeof(struct NODE));
curr[layer]->data =
((path >> (layer - 1)) & 1)? layer : -layer;
}
}
return curr[0];
}
The code assumes that negative integers on the target CPU are two`s complement.