У меня есть два метода: первый метод вызывает второй метод из forloop, но второй метод возвращает первый метод с идентификатором поддерева. Является ли это формой рекурсии? Хотя тот же самый метод не вызывает себя, существует ли риск или любых других проблем, которые могут быть связаны с обычными рекурсивными методами?
void AddItems(int id)
{
var items = GetItems(id);
foreach (var item in items)
{
AddItem(item);
}
}
void AddItem(Item item)
{
DoSomething(item);
AddItems(item.subItemId);
}
EDIT: Есть ли способ сделать это итеративным? Я использую С#.
Как правило, если он называет себя, прямо или косвенно, на том же или на разных данных это рекурсия.
Если он не является рекурсивным (что это не так), рекурсия подвержена переполнениям стека. В частности, subItemId
который совпадает с его родительским идентификатором, приведет к циклу, вызвав SO.
Является ли это формой рекурсии?
Да; это взаимная рекурсия.
Есть ли риск или любых других проблем, которые могут быть связаны с обычными рекурсивными методами?
Да.
Есть ли способ сделать это итеративным?
Да. Все рекурсивные алгоритмы имеют итеративную форму, поэтому это делает. Я отмечаю, что нет требования, чтобы итеративная форма была легко найти или легко понять. Однако в этом случае итеративный алгоритм очень хорошо известен; это глубина первого обхода дерева. Сделайте поиск в Интернете, и вы быстро научитесь использовать явный стек или явную очередь для управления обходами дерева итеративно.
Это не прямая рекурсия, потому что рекурсия определяется как метод вызывает себя. Но в вашем случае есть косвенная рекурсия. Итак, да, вы рискуете StackOverFlowError
да, это довольно просто:
void AddItems(int id) {
tempID = id;
bool loop = true;
while(loop) {
var items = GetItems(id);
for each(var item in Items) {
DoSomething(item);
id = item.subitemID;
continue;
}
loop = false;
}
}
Не проверял его. Но должен сделать трюк... Вы также можете взглянуть на инструкцию GOTO http://msdn.microsoft.com/en-IN/library/13940fs2.aspx
Рекурсия происходит, когда функция вызывает себя. В обоих элементах void() s функция вызывает себя. Тем не менее, каждая рекурсивная функция нуждается в базовом случае, или она будет бесконечно возвращаться, что будет иметь место здесь. Сделайте домашнее задание, есть тонны сайтов, объясняющих рекурсию.