Введение
Я создаю веб-приложение HTML5, которое создает визуальное представление двоичного дерева поиска из заданного списка чисел.
В настоящее время у меня есть алгоритм, который вычисляет визуальное расстояние между узлами в каждой строке на основе максимальной глубины дерева (которое является значением base-0):
offset = 50
offset *= pow(2, maxDepth - currentDepth)
Отсюда позиция node определяется с использованием этого смещения и x-позиции его родителя.
Алгоритм работает хорошо, потому что он всегда способен приспосабливаться к самому широкому дереву любой глубины. Однако это также делает дерево излишне широким в разы.
Примеры
Разветвление дерева влево (слишком широко):
ветвление дерева слева http://f.cl.ly/items/0c0t0L0L0o411h092G2w/left.png
Разветвление дерева с обеих сторон (левая и правая стороны могут быть ближе друг к другу).
Разделение дерева на обе стороны http://f.cl.ly/items/0r3X1j0w3r1D3v1V1V3b/left-right.png
В идеале, вышеупомянутое дерево должно быть сформировано как пирамида с меньшей шириной и с прямыми сторонами, как показано ниже:
Сбалансированное дерево (в случае, когда алгоритм работает лучше всего):
Сбалансированное дерево http://f.cl.ly/items/203m2j2i3P1F2r2T3X02/balanced.png
Реализация
Свойства
Я использую Backbone.js для создания узлов из модели node. Каждый node имеет следующие свойства:
- родительский (родительский node)
- left (левый дочерний элемент node)
- справа (правый ребенок node)
- x (x-позиция node в пикселях)
- y (y-позиция node в пикселях)
Вышеуказанные свойства x и y вычисляются в зависимости от направления ветвления node:
if (parent.get('left') === node) {
x = parentX - offsetX;
y = parentY + offsetY;
} else if (parent.get('right') === node) {
x = parentX + offsetX;
y = parentY + offsetY;
}
На этом этапе свойства x и y - это точные значения, используемые для размещения узлов (каждый из них помещен как абсолютный в элемент контейнера).
Методы
- getDepth() (возвращает глубину базового 0 в node)
- getMaxDepth() (возвращает глубину последней строки в дереве)
- getRow (n) (возвращает массив всех узлов на глубине-n)
Вопрос
Поэтому мой вопрос прост:
Каков наилучший алгоритм для минимизации эстетической ширины моего двоичного дерева?