@AntonGoretskiy

Как быстро выполнить топологическую сортировку дерева из списка?

Здравствуйте!
Имеется список с атрибутами(Name, ID, ParentID), который представляет из себя дерево разного уровня вложенности. Как наиболее быстро восстановить дерево из этого списка? Спасибо
  • Вопрос задан
  • 2493 просмотра
Решения вопроса 1
Ну например так:

class TreeNode:
    def __init__(self):
        self.children = []
        self.name = None

    def add_child(self, child):
        self.children.append(child)

    def set_name(self, name):
        self.name = name

entries = {}
for entry in data:
    parent = entries.get(entry.ParentID, TreeNode())
    child = entries.get(entry.ID, TreeNode())
    parent.add_child(child)
    child.set_name(entry.Name)
    entries[entry.ParentID] = parent
    entries[entry.ID] = child

root = entries[RootID]


В зависимости от используемого "словаря" (в примере entries) получаем разную сложность. Если, например, известно что ID - это числа от 0 до N, то можно использовать как словарь простой массив - тогда получаем гарантированно O(n), если пишем на C++ и в качестве словаря используем std::map или TreeMap в Java, то O(n log n).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@throughtheether
human after all
Я не вполне понял задачу, которую вы пытаетесь решать.
Как быстро выполнить топологическую сортировку дерева из списка?
У вас фактически заданы дуги (arcs) графа. Вы можете из этих данных заполнить более удобную структуру данных (adjacency list, например) и на ней уже запустить алгоритм топологической сортировки. Например, основанный на поиске в глубину. То есть, при помощи DFS (depth-first search, поиск в глубину) ищем ноду (вершину, node, vertex), из которой нет исходящих дуг (sink node), присваиваем ей значение, равное количеству нод, удаляем ее из графа, повторяем. Число - позиция ноды в результирующем списке. Сложность O(m+n), где n - число нод, m - число дуг. Это если вам достаточно топологически отсортированного списка нод.
Как наиболее быстро восстановить дерево из этого списка?
Это уже другой вопрос. Что вы имеете в виду? В каком смысле 'восстановить'? У вас дерево (как частный случай графа) уже задано списком дуг фактически, в каком виде вам его необходимо представить?
Если в виде (Name, ID, ChildID), то мне представляется, что за O(m) можно создать подобную структуру с фактически перевернутыми (относительно заданного дерева) дугами. Для каждого кортежа (Name, ID, ParentID) создаете (или обновляете поле Name, если нода уже существует) ноду (Name, ID), ноду ParentID (если она не создана), у ноды ParentID указываете наследника (child node) ID.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы