LINUX.ORG.RU

Как избавиться от рекурсии?

 


0

1
void func(int a, bool arr[]) {
    arr[a] = true;
    // print
    for(list<int>::iterator i = global_list[a].begin(); i != global_list[a].end(); ++i)
        if(!arr[*i])
            func(*i, arr);
}

Как я понимаю, нужно это перевести в стековую реализацию, но я не понимаю как.

Дополнения: это был псевдокод, вот полный код http://pastebin.com/fa3kyPU1



Последнее исправление: cisido (всего исправлений: 3)

у тебя тут хвостовая рекурсия. читай про нее. ее для этого и используют

anonymous
()
Ответ на: комментарий от cisido

Как я понимаю, нужно это перевести в стековую реализацию

из твоего поста не очевидно почему ты понимаешь именно так и зачем через стек

anonymous
()
Ответ на: комментарий от anonymous

сказали сделать через стек :). Переписать на цикл просто, а вот...

cisido
() автор топика
Ответ на: комментарий от anonymous

у тебя тут хвостовая рекурсия. читай про нее. ее для этого и используют

где там у него хвостовая рекурсия?

MKuznetsov ★★★★★
()

Зачем тебе стек? А что вообще делает эта func?

Что передаётся (первый раз) в параметр a?

Используется итератор i от некоторой коллекции global_list - как индекс для _другого_ массива - а так можно вообще?

BattleCoder ★★★★★
()
Ответ на: комментарий от anonymous

Нет, не хвостовая - там вызов функции внутри for. Соответственно, много раз.

BattleCoder ★★★★★
()
Ответ на: комментарий от anonymous

насколько понял по невнятным объяснениям, ТС`у надо преобразовать в форму с хвостовой рекурсией, но прогуленные лекции и семинары не позволяют даже понять задачку.

скорее в job. Или книгу посоветовать

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

я дополнил вопрос кодом. На большую оценку нужно в стек. Спасибо.

cisido
() автор топика
Ответ на: комментарий от cisido

Обход графов? Смотри, когда ты делаешь рекурсивный вызов функции - ты увеличиваешь размер стека вызовов. В этом стеке вызовов может что-то храниться (например, передаваемые параметры, которые меняются от вызова к вызову). Вместо того, чтобы хранить эти данные в стеке вызовов (неявно) запихивай их в отдельный стек явно. И также потом их оттуда доставай.

Это в общих чертах если.

BattleCoder ★★★★★
()
Ответ на: комментарий от cisido

учись, студент.

struct stack_element {
	int v;
	bool* visited;
	stack_element(int v, bool* visited):v(v),visited(visited){};
}; 
void Graph::DFSUtil(int _v, bool _visited[])
{
    std::queue<stack_element> local_stack;
    local_stack.push(stack_element(_v,_visited));
    
    while (!local_stack.empty())
    {
    stack_element el = local_stack.front(); 
    int v = el.v;
    bool* visited = el.visited;
    local_stack.pop();
    // ----
    visited[v] = true;
    cout << v << " ";
    list<int>::iterator i;
    for(i = adj[v].begin(); i != adj[v].end(); ++i)
        if(!visited[*i])
        {	
        	//DFSUtil(*i, visited);
        	visited[*i] = true;
        	local_stack.push(stack_element(*i,visited)); 
        }
    }
    //----
}
queue вместо stack чтобы сохранить порядок эквивалентный исходному примеру на перформанс насрать заради наглядности.

anonymous
()
Ответ на: комментарий от anonymous

теперь буду использовать этот пример везде. Огромное спасибо.

cisido
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.