Divide & Conquer. Create the line lists of the subtrees, concatenate the lines and prepend the String
for the root node of the subtree. Also make sure the lines have the same length and all are centered:
static String pad(String s, int lengthRigth, int length) {
StringBuilder sb = new StringBuilder();
for (int i = length - lengthRigth - s.length(); i > 0; i--) {
sb.append(' ');
}
sb.append(s);
for (int i = 0; i < lengthRigth; i++) {
sb.append(' ');
}
return sb.toString();
}
static StringBuilder withSpacesAppended(String s, int spaceCount) {
StringBuilder sb = new StringBuilder(s.length()+spaceCount).append(s);
for (int i = 0; i < spaceCount; i++) {
sb.append(' ');
}
return sb;
}
static void joinLists(List<String> list1, List<String> list2) {
int i;
final int size = list2.size();
for (i = 0; i < size; i++) {
list1.set(i, withSpacesAppended(list1.get(i), 2).append(list2.get(i)).toString());
}
}
static List<String> createTreeStrings(int index, int[] array) {
int child1 = 2 * index + 1;
int child2 = 2 * index + 2;
if (child1 >= array.length) {
return new ArrayList<>(Collections.singletonList(toText(index, array)));
} else {
List<String> childList1 = createTreeStrings(child1, array);
if (child2 < array.length) {
joinLists(childList1, createTreeStrings(child2, array));
}
String text = toText(index, array);
int currentLength = childList1.get(0).length();
if (currentLength >= text.length()) {
text = pad(text, (currentLength - text.length()) / 2, currentLength);
} else {
for (int i = 0, size = childList1.size(); i < size; i++) {
childList1.set(i, pad(childList1.get(i), (currentLength - text.length()) / 2, currentLength));
}
}
childList1.add(0, text);
return childList1;
}
}
static String toText(int index, int[] array) {
return Integer.toString(array[index]) + '(' + index + ')';
}
Example use:
createTreeStrings(0, new int[]{84, 81, 41, 79, 17, 38, 33, 15, 61, 6}).forEach(System.out::println);
createTreeStrings(0, new int[]{Integer.MAX_VALUE, 6}).forEach(System.out::println);