2012-02-19 7 views
0

У меня проблема с поворотом этого кода:Как написать итерационный DFS, который отсчитывает потомок узла в дереве

void dfs(int i = 1) { 
    static int preorder = 0; 
    d[i].first = ++preorder; 
    d[i].second = 1; 
    for (list<int>::iterator it = tree[i].begin(); it != tree[i].end(); ++it) { 
    dfs(*it); 
    d[i].second += d[*it].second; 
    } 
} 

в повторяющийся. Как вы можете видеть, он находит номер предварительного заказа каждого узла и количество его потомков. Я должен это сделать, из-за ограничения памяти (размер данных до 10^6).

Заранее спасибо.

+0

Это не хорошее использование статической переменной ... –

+0

Почему? Эта функция вызывается только один раз. – rAum

+0

Вы называете это рекурсивно, поэтому на самом деле его называют много. –

ответ

0

Наконец-то я понял это. Это может быть не так быстро, но это достаточно быстро, чтобы пройти тесты без лишней памяти. Мне нужны указатели от ребенка к его отцу (всего 8 МБ массива под названием ojciec) и определить, когда узел впервые посещен (идет вниз) или нет (вверх). Вот мой код:

void dfs() 
{ 
    int preorder = 0; 
    int i; 
    stack<int, list<int> > stos; 

    stos.push(1); 
    while(!stos.empty()) { 
    i = stos.top(); 

    if (order[i] == 0) { // node is first time visited 
     order[i] = ++preorder; // set default values 
     size[i] = 1; 
    } 

    if (dynastia[i] != NULL) // can go left... 
     stos.push(pop(&dynastia[i])); // so take first child, remove it and release memory 
    else { 
     stos.pop(); 
     size[ojciec[i]] += size[i]; // adding total number of descendants to father 
    } 
    } 
} 
0

DFS - это рекурсивный алгоритм.

Если вы пытаетесь избежать пробега в стеке, вы можете использовать явный стек (преобразовать неявный стек вызовов в явный стек узла). Но я не думаю, что вы можете уйти от того факта, что это рекурсивный алгоритм.

Даже если вы используете явный стек, у вас все еще может быть нехватка памяти. Это зависит от объема памяти в вашей системе и от формы дерева. Но в большинстве случаев он, по крайней мере, избегал бы неприятного сбоя (вы можете обнаружить, когда вы исчерпали память кучи).

+0

Если узлы имеют родительские указатели, t нужен стек. –

+0

Я знаю это. Я могу писать простые dfs, используя стек, но у меня проблема с моей версией, потому что я использую backtracking для подсчета потомков и не знаю, как сделать его итеративным. У меня есть 32 МБ ОЗУ, и в худшем случае у меня будет 10^6 узлов, а дерево будет просто списком, поэтому невозможно использовать повторение ... – rAum

+0

@OliCharlesworth: узлы hmm не имеют родительских указателей, но может быть, правильно попробовать. Спасибо;) – rAum

 Смежные вопросы

  • Нет связанных вопросов^_^