Рекурсивный обход дерева в порядке уровня

У меня есть следующая рекурсивная структура данных и метод, повторяющий ее. При этом он должен добавить уникальный номер n к каждому node, например. его соответствующее число в обход уровня порядка в дереве.

var data = {
    children: [
        { children: [ ... ] },
        { children: [ ... ] },
        { children: [ ... ] },
        ...
    ]
}

var process = function (node) {
    node.children.forEach(child, function () {
        process(child);
    });
    return node;
}

Как я могу достичь этого без изменений структуры данных и минимальных изменений в функции обработки? Результат process(data) должен быть

var data = {
    n: 1
    children: [
        { n: 2, children: [ ... ] },
        { n: 3, children: [ ... ] },
        { n: 4, children: [ ... ] },
        ...
    ]
}

Ответы

Ответ 1

Используйте очередь для хранения узлов на каждом уровне. Используйте null, чтобы отметить конец одного уровня.

Изначально вставьте корневой каталог node и null в очередь. Затем итерации очереди, нажмите детей каждого node в очередь и отметьте непустой элемент. Когда вы сталкиваетесь с элементом null, нажмите новый. Таким образом, два последовательных null означают конец итерации.

var process = function (node) {
    var queue = [node, null];
    var i = 0, n = 1;
    while (queue[i] != null || (i == 0 || queue[i-1] != null)) {
        if (queue[i] == null) {
            queue.push(null);
        }
        else {
            queue[i].n = n++;
            queue[i].children.forEach(function (elem) {
                queue.push(elem);
            });
        }
        i++;
    }
}

process(data);
console.log(data);

Я использовал Array для очереди и не удалял посещаемые элементы (требуется O (n)). Если пространство, затраченное на queue, является узким местом, вы можете заменить его другой реализацией очереди и немного изменить алгоритм.