Пройдите по графику, построив набор перевернутых ребер и список листовых узлов.
Выполните топологическую сортировку перевернутых ребер, используя для начала листовые (теперь корневые) узлы.
Построить перевернутый граф на основе перевернутых ребер, начиная с конца отсортированного списка. Поскольку узлы построены в обратном топологическом порядке, вы гарантированно создали дочерние элементы данного узла перед построением узла, поэтому создание неизменного представления возможно.
Это либо O (N), если вы используете структуры для своего промежуточного представления, которые отслеживают все ссылки в обоих направлениях, связанных с узлом, либо O (NlnN), если вы используете сортировку, чтобы найти все ссылки узла. Для небольших графов или языков, которые не страдают от переполнения стека, вы можете просто построить график лениво, а не явно выполнять топологическую сортировку. Так что от того, как все это будет отличаться, зависит немного, что вы реализуете.
A -> (B -> G, C -> (E -> F, D -> F))
original roots: [ A ]
original links: [ AB, BG, AC, CE, EF, CD, DF ]
reversed links: [ BA, GB, CA, EC, FE, DC, FD ]
reversed roots: [ G, F ]
reversed links: [ BA, CA, DC, EC, FE, FD, GB ] (in order of source)
topologically sorted: [ G, B, F, E, D, C, A ]
construction order : A, C->A, D->C, E->C, F->(D,E), B->A, G->B