Shovel the list by building a full tree (if it is a tree, of course). Take the next peak from the list, stick it in place, repeat.
When will you have (I write with the notation […]
≡ Array(…)
)
[1 => [5 => [9 => [14 => …, 15 => [], 16 => []], 10 => …, 23 => …, 24 => …], 7 => …, 21 => …, 22 => …], 2 => …, 3 => …, 4 => …]
That working with wood will be trivial. The resulting tree, of course, is to save and use instead of a list wherever required.
If you do not want to build a tree, or cycles are possible in the graph, then just look for the next descendants and add. Pseudocode:
function children(graph, node) { // graph — ваш массив, node — начальный ключ result = {node}; // Множество-результат pending = {node}; // Множество узлов, ожидающих обработки while (count(pending) > 0) { // Пока есть непросмотренные узны node = pending.pop(); // Вытаскиваем из мн-ва любой узел if (!result.contains(node)) { // Защита от циклов, если уже видели такой children = array_keys(graph, node, true); // Находим непосредств. детей pending += children; // Запоминаем для обработки result += children; // И добавляем к результату } } return result; }
I hope the idea is clear, and it will be easy to do next.
I used the pseudo-syntax {}
to denote the set. In PHP, there is no “set” type, but it can be emulated by an associative array in which key values are ignored.