@vasIvas

Как построить произвольное дерево?

Имеется дерево где ноды имеют неограниченное количество детей.
Нужно расставить их на плоскости так, чтобы между братьями был минимальный размер A,
а между соседями минимум B.
Стоит упомянуть что ширина ноды не фиксированная, но это я думаю не столь важно.

Если кто-то знает, как это решить, объясните на словах.

Нода выглядит так -
getLeftNode():Node
getRightNode():Node
insertNode(node:Node):void
getNodeAt(index:uint):Node

parent:Node

next:Node
prev:Node
// сюда я пишу значение на которое брат должен быть отложен от брата
indent:Number 

// сюда записываю общую ширину детей вместе с indent
tierWidth:Number

width:Number
height:Number

// служит для записи координат
position:Point


Если нужны какие-то свойства, то скажите.
  • Вопрос задан
  • 555 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Придумал.
Для каждого узла делаем координату deltaX — смещение по X относительно отца.
И динамический массив из пар (x1, x2) — границы деревьев на всех уровнях.

алг рекурсия(узел: Узел)
  длина_мас = 0

  // Прогоним алгоритм для сыновей, рассчитаем длину массива
  для всех сыновей (узел) → сын
    рекурсия(сын)  // ыгы, в основе банальный обход в глубину
    длина_мас = макс(длина_мас, сын.границы.длина)
  длина_мас = длина_мас + 1

  разложить сыновей на плоскости, руководствуясь их массивами границ
     и вашим чувством прекрасного;  соответственно присвоить ИХ deltaX
     (оставлю это как домашнее задание)

  // Рассчитаем границы дли нашего узла
  границы.установить_размер(длина_мас)  
  границы.заполнить(левая=+M, правая=—M)
  полширины = узел.ширина / 2
  границы[0] = (левая = −полширины, правая = узел.ширина − полширины)
  для всех сыновей (узел) → сын
    для i = [0 .. сын.границы.длина)      
      узел.границы[i+1].левая = мин(
           узел.границы[i+1].левая, сын.границы[i].левая + сын.deltaX)
         // если сыновья идут слева направо, этого хватает!
      узел.границы[i+1].правая = сын.границы[i].правая + сын.deltaX
    сын.границы.установить_размер(0)    // массив больше не нужен

// Если же нужны точные координаты каждого узла…

алг уточнитьКоординаты(узел: Узел; Y: целое)
  узел.коорд.Y = Y
  Yсына = Y + высота_яруса
  для всех сыновей (узел) → сын
    сын.коорд.X = узел.коорд.X + сын.deltaX
    уточнитьКоординаты(сын, Yсына)


+M — запредельно большое число
−M — отрицательное число с запредельно большим модулем
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы