簡體   English   中英

如何編寫計算樹中節點后代的迭代DFS

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM