[英]How to write iterative DFS which counts descendants of a node in a tree
我在轉換此代碼時遇到問題:
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),我必須這樣做。
提前致謝。
DFS是一種遞歸算法。
如果要避免用完堆棧空間,可以使用顯式堆棧(將隱式調用堆棧轉換為顯式節點堆棧)。 但是我認為您不能回避它是遞歸算法的事實。
即使您使用顯式堆棧,仍然可能會用完內存。 這取決於系統中的內存量以及樹的形狀。 但是在大多數情況下,這至少可以避免令人討厭的崩潰(您可以檢測出堆內存何時用完)。
終於我明白了。 它可能沒有那么快,但是足夠快以通過測試而又不會占用太多內存。 我需要從孩子到父親的指針(只有8 MB的數組,稱為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
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.