V
V
vasIvas2015-05-25 20:08:12
Algorithms
vasIvas, 2015-05-25 20:08:12

How to build an arbitrary tree?

There is a tree where nodes have an unlimited number of children.
It is necessary to arrange them on a plane so that between the brothers there is a minimum size A,
and between neighbors at least B.
It is worth mentioning that the width of the node is not fixed, but I think this is not so important.
If someone knows how to solve this, please explain in words.
Node looks like this -

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

If you need any features, please let me know.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2015-05-25
@vasIvas

Invented.
For each node, we make the deltaX coordinate - the X offset relative to the father.
And a dynamic array of pairs (x1, x2) - the boundaries of trees at all levels.

алг рекурсия(узел: Узел)
  длина_мас = 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 - prohibitively large number
−M - negative number with prohibitively large modulus

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question