Как нарисовать древовидную структуру? (Алгоритм рекурсии дерева распределения двумерного пространства?)

У меня произвольная древовидная структура узлов. Я хочу нарисовать это дерево, чтобы предоставить пользователям визуальное представление. Мне нужно рекурсировать по дереву и для каждого узла добавить графический элемент в список, а затем просто нарисовать список элементов после завершения рекурсии дерева. Рекурсия и рисование элементов, конечно, тривиальны - немного сложнее, как расположить графические узлы, чтобы они не перекрывались с другими ветвями.

Я использую Android, но это не важно-я ищу подход, возможно, алгоритм, который может поддерживать изображение 2D-пространства, когда он проходит над деревом, поэтому он просто выделяет наиболее подходящие координаты для каждого узла, когда он делает проход.

какие идеи?

обновление

это статья с лучшим и наиболее полным алгоритмом.

5 ответов


Я бы попробовал алгоритм Уокера. вот академическая статья на алгоритм. Если вы хотите посмотреть код, посмотрите на NodeLinkTreeLayout на Prefuse. Prefuse является открытым исходным кодом, поэтому не должно быть никаких проблем с адаптацией кода к вашей ситуации, если вы следуете условиям лицензии.


я предлагаю рисовать дерево линейно. Вы делаете это, используя какой-то движущийся "курсор рисования".

вы можете сохранить атрибут width для каждого узла, который рассчитывается следующим образом:

  • the width отпуска - 1
  • the width внутреннего узла-это сумма всех детских widths

затем вы рисуете корень "в первой строке" в середине, что означает, что вы просто берете корень width'ы половина.

затем вы создаете сетку над изображением так, чтобы каждая линия сетки соответствовала одной строке resp. один шаг слева направо, и каждое пересечение линий сетки может содержать узел, и каждый узел имеет достаточно места.

затем вы перебираете детей и во время итерации накапливаете детские widths и нарисуйте детей "в следующей строке". Рисовать currentChild, вы перемещаете курсор рисования currentWidth/2 вправо, рисуйте currentChild, и переместить рисование курсором оставшегося currentWidth/2 справа.

для того, чтобы получить узлы в хорошем порядке, вы можете рассмотреть широту первого поиска.


посмотри точка. Вы можете преобразовать свое дерево в точечное представление, а затем использовать Graphviz визуализируйте в любом формате, как вам нравится. Например помощи Doxygen используется для представления структуры программы.


Graphviz и mfgraph являются мощными, но они для общих графов и, вероятно, излишни для деревьев.

попробуйте погуглить на дереве + макет + алгоритм или посмотреть графическое дерево Javascript с макетом. Последний старый, но он использует HTML canvas и javascript, и он объясняет код, поэтому и код, и подход должны быть переносимыми.


в зависимости от характера ваших данных, a TreeMap может быть более подходящим, чем представление Лего.