Цель: попрактиковаться в работе с древовидными структурами данных (представленными объектами) и рекурсивными/итеративными алгоритмами.
value
текущего узла в массив результатов.children
рекурсивно вызовите эту же функцию.value
в массив результатов.children
) в стек. Важно: чтобы сохранить правильный порядок обхода (слева направо), дочерние узлы нужно добавлять в стек в обратном порядке (справа налево).null
(пустое дерево).Этот подход является наиболее интуитивным для древовидных структур, поскольку сама структура дерева рекурсивна.
Код с комментариями:
const depthFirstSearch = (tree) => {
// 1. Обрабатываем крайний случай: если дерево пустое (null), возвращаем пустой массив.
if (!tree) {
return [];
}
// 2. Создаем массив для хранения результата обхода.
const result = [];
// 3. Определяем вложенную рекурсивную функцию `traverse` (обход).
// Она будет вызываться для каждого узла (объекта) в дереве.
function traverse(node) {
// 4. Добавляем значение текущего узла в массив результатов.
// Это "посещение" узла.
result.push(node.value);
// 5. Перебираем всех дочерних элементов текущего узла.
// Убеждаемся, что у узла есть дочерние элементы, прежде чем их перебирать.
if (node.children) {
for (const child of node.children) {
// 6. Для каждого дочернего узла рекурсивно вызываем ту же функцию `traverse`.
// Это погружение "вглубь" дерева.
traverse(child);
}
}
}
// 7. Начинаем обход, вызывая `traverse` для корневого узла дерева.
traverse(tree);
// 8. Возвращаем массив с результатами обхода.
return result;
};
Как это работает:
null
. Если да, то обход невозможен, и она возвращает пустой массив.result
, в который будут собираться значения узлов.traverse
:
node
, она немедленно добавляет значение этого узла (node.value
) в массив result
.children
этого узла.traverse(child)
). Этот шаг является ключевым в рекурсии.traverse(tree)
запускает рекурсивный процесс с корневого узла.traverse(tree)
завершит свою работу, массив result
будет содержать все значения узлов в правильном порядке.Этот подход использует структуру данных “стек” (Stack) для отслеживания узлов, которые нужно посетить. Он позволяет избежать глубокой рекурсии, которая может привести к переполнению стека вызовов.
Код с комментариями:
const depthFirstSearch = (tree) => {
// 1. Обрабатываем крайний случай: если дерево пустое, возвращаем пустой массив.
if (!tree) {
return [];
}
// 2. Создаем массив для хранения результата.
const result = [];
// 3. Создаем стек и сразу помещаем в него корневой узел (объект).
const stack = [tree];
// 4. Запускаем цикл, который продолжается, пока в стеке есть узлы.
while (stack.length > 0) {
// 5. Извлекаем последний узел из стека (принцип LIFO — Last-In, First-Out).
const node = stack.pop();
// 6. "Посещаем" узел: добавляем его значение в массив результатов.
result.push(node.value);
// 7. Перебираем дочерние узлы текущего узла В ОБРАТНОМ ПОРЯДКЕ.
// Это ключевой момент для правильного порядка обхода.
if (node.children) {
for (let i = node.children.length - 1; i >= 0; i--) {
// 8. Помещаем каждого дочернего узла в стек.
stack.push(node.children[i]);
}
}
}
// 9. Возвращаем массив с результатами.
return result;
};
Как это работает:
null
и создается массив result
. Также создается stack
и в него сразу помещается корневой объект tree
.while
: Цикл продолжается, пока стек не опустеет.stack.pop()
.node.value
) добавляется в result
.while
заканчивается, все узлы были обработаны, и функция возвращает result
.Напишите функцию depthFirstSearch
, которая принимает корневой узел дерева (представленный в виде объекта) и возвращает массив значений всех узлов в порядке их обхода в глубину (DFS, Depth-First Search).
Обход в глубину — это алгоритм обхода или поиска в древовидной структуре данных. Алгоритм начинается с корневого узла и исследует каждую ветвь как можно глубже, прежде чем вернуться назад (backtracking).
Каждый узел дерева — это объект со следующей структурой:
{
value: any, // Значение узла (любого типа)
children: Array<object> // Массив дочерних узлов (таких же объектов)
}
Для дерева, представленного объектом:
const tree = {
value: 'A',
children: [
{
value: 'B',
children: [
{ value: 'D', children: [] }
]
},
{
value: 'C',
children: [
{ value: 'E', children: [] },
{ value: 'F', children: [] }
]
}
]
};
Результат вызова depthFirstSearch(tree)
должен быть: ['A', 'B', 'D', 'C', 'E', 'F']
.
depthFirstSearch
.tree
), который является объектом или null
.tree
равен null
, функция должна вернуть пустой массив.Цель: попрактиковаться в работе с древовидными структурами данных (представленными объектами) и рекурсивными/итеративными алгоритмами.
value
текущего узла в массив результатов.children
рекурсивно вызовите эту же функцию.value
в массив результатов.children
) в стек. Важно: чтобы сохранить правильный порядок обхода (слева направо), дочерние узлы нужно добавлять в стек в обратном порядке (справа налево).null
(пустое дерево).Этот подход является наиболее интуитивным для древовидных структур, поскольку сама структура дерева рекурсивна.
Код с комментариями:
const depthFirstSearch = (tree) => {
// 1. Обрабатываем крайний случай: если дерево пустое (null), возвращаем пустой массив.
if (!tree) {
return [];
}
// 2. Создаем массив для хранения результата обхода.
const result = [];
// 3. Определяем вложенную рекурсивную функцию `traverse` (обход).
// Она будет вызываться для каждого узла (объекта) в дереве.
function traverse(node) {
// 4. Добавляем значение текущего узла в массив результатов.
// Это "посещение" узла.
result.push(node.value);
// 5. Перебираем всех дочерних элементов текущего узла.
// Убеждаемся, что у узла есть дочерние элементы, прежде чем их перебирать.
if (node.children) {
for (const child of node.children) {
// 6. Для каждого дочернего узла рекурсивно вызываем ту же функцию `traverse`.
// Это погружение "вглубь" дерева.
traverse(child);
}
}
}
// 7. Начинаем обход, вызывая `traverse` для корневого узла дерева.
traverse(tree);
// 8. Возвращаем массив с результатами обхода.
return result;
};
Как это работает:
null
. Если да, то обход невозможен, и она возвращает пустой массив.result
, в который будут собираться значения узлов.traverse
:
node
, она немедленно добавляет значение этого узла (node.value
) в массив result
.children
этого узла.traverse(child)
). Этот шаг является ключевым в рекурсии.traverse(tree)
запускает рекурсивный процесс с корневого узла.traverse(tree)
завершит свою работу, массив result
будет содержать все значения узлов в правильном порядке.Этот подход использует структуру данных “стек” (Stack) для отслеживания узлов, которые нужно посетить. Он позволяет избежать глубокой рекурсии, которая может привести к переполнению стека вызовов.
Код с комментариями:
const depthFirstSearch = (tree) => {
// 1. Обрабатываем крайний случай: если дерево пустое, возвращаем пустой массив.
if (!tree) {
return [];
}
// 2. Создаем массив для хранения результата.
const result = [];
// 3. Создаем стек и сразу помещаем в него корневой узел (объект).
const stack = [tree];
// 4. Запускаем цикл, который продолжается, пока в стеке есть узлы.
while (stack.length > 0) {
// 5. Извлекаем последний узел из стека (принцип LIFO — Last-In, First-Out).
const node = stack.pop();
// 6. "Посещаем" узел: добавляем его значение в массив результатов.
result.push(node.value);
// 7. Перебираем дочерние узлы текущего узла В ОБРАТНОМ ПОРЯДКЕ.
// Это ключевой момент для правильного порядка обхода.
if (node.children) {
for (let i = node.children.length - 1; i >= 0; i--) {
// 8. Помещаем каждого дочернего узла в стек.
stack.push(node.children[i]);
}
}
}
// 9. Возвращаем массив с результатами.
return result;
};
Как это работает:
null
и создается массив result
. Также создается stack
и в него сразу помещается корневой объект tree
.while
: Цикл продолжается, пока стек не опустеет.stack.pop()
.node.value
) добавляется в result
.while
заканчивается, все узлы были обработаны, и функция возвращает result
.Напишите функцию depthFirstSearch
, которая принимает корневой узел дерева (представленный в виде объекта) и возвращает массив значений всех узлов в порядке их обхода в глубину (DFS, Depth-First Search).
Обход в глубину — это алгоритм обхода или поиска в древовидной структуре данных. Алгоритм начинается с корневого узла и исследует каждую ветвь как можно глубже, прежде чем вернуться назад (backtracking).
Каждый узел дерева — это объект со следующей структурой:
{
value: any, // Значение узла (любого типа)
children: Array<object> // Массив дочерних узлов (таких же объектов)
}
Для дерева, представленного объектом:
const tree = {
value: 'A',
children: [
{
value: 'B',
children: [
{ value: 'D', children: [] }
]
},
{
value: 'C',
children: [
{ value: 'E', children: [] },
{ value: 'F', children: [] }
]
}
]
};
Результат вызова depthFirstSearch(tree)
должен быть: ['A', 'B', 'D', 'C', 'E', 'F']
.
depthFirstSearch
.tree
), который является объектом или null
.tree
равен null
, функция должна вернуть пустой массив.Редактор кода намеренно скрыт на мобильном.
Поверь, так лучше: я оберегаю тебя от искушения писать код в неидеальных условиях. Маленький экран и виртуальная клавиатура — не лучшие помощники для программиста.
📖 Сейчас: Изучи задачу, продумай решение. Действуй как стратег.
💻 Потом: Сядь за компьютер, открой сайт и реализуй все идеи с комфортом. Действуй как код-джедай!