As the array represents a perfect binary tree, i.e., where all internal nodes have 2 children, and all the leaves are located at the same depth, the array length will always be a power of 2 minus 1. In the example it is 24-1. That power is the number of levels of the tree... which is one more than the tree's height. Let's call the height ℎ, then the size of the input array is 2ℎ+1-1.
We can use binary representations of position numbers. With position I mean the index plus 1. So the root has position 1, and its children have positions 2 and 3. Represent each position in binary representation, using ℎ+1 binary digits. So for the example input, you would use 4 digits. To know the range of positions of the leaves below a given position, see how many leading zeroes there are in the position number.
For instance, take position 3 (where the example tree has value 5), which is 0011 in binary with 4 digits. It has 2 leading zeroes.
Now remove those leading zeroes. For the example we get binary 11.
Now complete these digits at the right with any digits to have again 4 digits. This represents the range of positions of the leaves. In the example: 1100 to 1111. You can then turn that back to decimal and subtract 1 to get the indices: 11,12,13,14.
Here is a table that does this calculation for all the internal nodes in your example:
Index |
Value |
Position |
Position (binary) |
Shift |
Range |
In decimal |
Indices |
0 |
15 |
1 |
0001 |
1*** |
1000-1111 |
8-15 |
7-14 |
1 |
10 |
2 |
0010 |
10** |
1000-1011 |
8-11 |
7-10 |
2 |
5 |
3 |
0011 |
11** |
1100-1111 |
12-15 |
11-14 |
3 |
3 |
4 |
0100 |
100* |
1000-1001 |
8,9 |
7,8 |
4 |
7 |
5 |
0101 |
101* |
1010-1011 |
10,11 |
9,10 |
5 |
5 |
6 |
0110 |
110* |
1100-1101 |
12,13 |
11,12 |
6 |
0 |
7 |
0111 |
111* |
1110-1111 |
14,15 |
13,14 |