Для координаты Y итерируйте по родителям и суммируйте высоту каждого родительского узла.Для каждого родителя добавьте также интервал белого, например
int y = 0;
Parent parent = child.getParent();
while(parent != null) {
y += 10; // spacing
y += parent.getHeight();
parent = parent.getParent(); // next iteration
}
Однако это не очень практичный подход.Скорее, вы должны повторять уровень за уровнем - начните с верхнего узла, затем с первых двух потомков, затем с 4 внуками и так далее.Например: добавьте верхний узел в список, просмотрите список и создайте новый список для всех их дочерних элементов, затем установите новый список на старый и продолжайте в цикле while, пока список не станет пустым.
Теперь для x-позиции это более сложно, так как хороший макет зависит от количества узлов на этом конкретном уровне.Если узел три всегда является двоичным и сбалансированным, то есть 2 степени n узлов на уровень.Если нет, вы должны сначала проверить, сколько узлов на уровень.Когда закончите, просто разделите ширину экрана на количество узлов и расположите их по порядку, добавляя к координате x по мере продвижения.
РЕДАКТИРОВАТЬ: я предпочитаю такой подход:
class BinaryTreeNode {
BinaryTreeNode left;
BinaryTreeNode right;
int x;
int y;
}
public void position(BinaryTreeNode root, int nodeHeight, int nodeWidth, int screenWidth, int screenHeight) {
List<BinaryTreeNode> nodes = new ArrayList<BinaryTreeNode>();
nodes.add(root);
int level = 0;
while(!nodes.isEmpty()) {
// we know now the number of nodes and the level
int y = level * nodeHeight;
// the x position depends on the number of nodes:
int widthPerNode = screenWidth / nodes.size();
int x = 0; // start at leftmost
// now have (fixed) y position and starting point for x (leftmost)
for(BinaryTreeNode node : nodes) { // for loop iterates in-order
node.y = y;
node.x = x; // TODO: center node within available space
x += widthPerNode;
}
// this level is complete, store all children in a list
List<BinaryTreeNode> childNodes = new ArrayList<BinaryTreeNode>();
for(BinaryTreeNode node : nodes) { // for loop iterates in-order
if(node.left != null) {
childNodes.add(node.left);
}
if(node.right != null) {
childNodes.add(node.right);
}
}
// continue to next level using the collected children as the new parents
nodes = childNodes;
level++;
}
// TODO: insert insets between nodes
// TODO: insert stop criteria for y outside screen
// TODO: insert stop criteria for x outside screen
// TODO: getters and setters
}
Кроме того, вы можете изменить этот метод, чтобы он возвращал вам узлы, которые должны быть нарисованы, если это не входит в ваш метод paint ().