Обход дерева объектов в C#

У меня есть дерево, состоящее из нескольких объектов, где каждый объект имеет имя (string), идентификатор (int) и, возможно, массив дочерних элементов одного типа. Как пройти по всему дереву и распечатать все идентификаторы и имена?

Я новичок в программировании и, честно говоря, у меня проблемы с осознанием этого, потому что я не знаю, сколько там уровней. Прямо сейчас я использую цикл foreach для получения родительских объектов непосредственно под корнем, но это означает, что я не могу получить дочерние объекты.

Я согласен. Упростите использование рекурсии.

Roy Astro 14.01.2009 19:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
21
1
46 769
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Алгоритм, использующий рекурсию, выглядит следующим образом:

printNode(Node node)
{
  printTitle(node.title)
  foreach (Node child in node.children)
  {
    printNode(child); //<-- recursive
  }
}

Вот версия, которая также отслеживает, насколько глубоко вложена рекурсия (т.е. печатаем ли мы дочерние элементы корня, внуков, правнуков и т. д.):

printRoot(Node node)
{
  printNode(node, 0);
}

printNode(Node node, int level)
{
  printTitle(node.title)
  foreach (Node child in node.children)
  {
    printNode(child, level + 1); //<-- recursive
  }
}

Что ж, вы всегда можете использовать рекурсию, но в сценарии программирования «реального мира» это может привести к плохим вещам, если вы не будете отслеживать глубину.

Вот пример, используемый для двоичного дерева: http://www.codeproject.com/KB/recipes/BinarySearchTree.aspx

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

Не могли бы вы проиллюстрировать альтернативу использованию рекурсии (т.е. нерекурсивную версию моего примера псевдокода)?

ChrisW 14.01.2009 19:43

Думаю, он был бы крупноватым и громоздким. Ваш пример определенно самый простой и легкий для понимания. Я просто пытался подчеркнуть, что рекурсия обычно плохая идея в производственной среде.

Alex Fort 14.01.2009 19:46

Если вы установите надлежащие проверки, чтобы убедиться, что он никогда не повторяется бесконечно, почему это плохая идея? Мы используем рекурсию в нескольких местах в нашей производственной среде, но ограничиваем уровень рекурсии.

Tom Anderson 14.01.2009 19:49

Вам нужно как-то отслеживать контекст: поэтому, если вы не собираетесь рекурсивно (сохраняя контекст в стеке программы), вам нужно сохранить его в куче (возможно, используя локальную переменную типа Stack)? Я не уверен, почему вы говорите, что это «обычно плохая идея», если допустить какое-то дерево с разумной глубиной?

ChrisW 14.01.2009 19:52

Если вы реализуете это, как упомянул Том Андерсон, отслеживая глубину и ограничивая ее, то с этим не будет никаких серьезных проблем. Однако для начинающего программиста довольно легко попасть в ситуацию переполнения стека.

Alex Fort 14.01.2009 19:54

Согласен с Томом Андерсоном. Я не понимаю, почему это плохая идея, если вы проверяете конечные условия, то есть «знаете, когда остановиться». Одно дело сказать «остерегайтесь бесконечной рекурсии», а другое - категорически заявить, что это обычно плохая идея для использования в сценариях программирования «реального мира».

felideon 14.01.2009 20:01

@Alex: Круто. Все еще привыкаю к ​​потоку здесь, в SO. :) Плюс нужно было обновить.

felideon 14.01.2009 20:05

Да, я знаю .. комментарии то появляются, то исчезают, кажется: P

Alex Fort 14.01.2009 20:07

Другие вопросы по теме