遍历双向连接的双向n树

时间:2014-11-25 11:36:52

标签: c++ algorithm data-structures

我有一个映射基因的多个剪接异构体的数据结构,这意味着图的每个元素可以是任何其他元素的前任或后继元素(不包括它自身)。 结构可能是A-B-C-D,A-C-E等等。

为了表示这一点,我将数据文件读入元素

class El {
  vector<El*> left, right;
  T content;
};

所以E包含的每个元素都是前辈和后继者,而前辈和后继者也链接回E.这是构造结构所必需的。为了搜索原因,有必要从结构的任何节点开始遍历,但是当使用简单的宽度或宽度第一种方法遍历时,这将导致无限圆(这里:以C开头;向左遍历:(B,A),( A);从A:(C,E),(B,C,...)向右移动,从C:(B,A)向左移动,...)

错误的代码(无限圆圈):

vector<El*> startingpoints;

void traverse(El* el = nullptr) {
  if (el == nullptr) {
    for (auto& node : startingpoints) {
      traverse(node);
    }
  }
  else {
    for (auto& ltEl : el->left) {
      traverse(ltEl);
    }
    std::cout << *El;
    for (auto& rtEl : el->right) {
      traverse(rtEl);
    }
  }
}

有人能提出正确的方法吗?

2 个答案:

答案 0 :(得分:0)

您可以向El类添加标记。 flag = 0表示您尚未处理此节点,而1表示节点已处理并因此停止。

答案 1 :(得分:0)

我目前的方法,基于Min Fu的想法:

class El {
  vector<El*> left, right;
  uint runID; // init to 0
  T content;
};

vector<El*> startpoints;

void traverse(El* el = nullptr) {
  static uint runID = 1;
  if (el == nullptr) {
    for (auto& node : startingpoints) {
      traverse(node);
      runID++;
    }
  }
  else {
    el->runID = runID;
      // predecessors
    for (auto& ltEl : el->left) {
      if (ltEL->runID != runID) {
        traverse(ltEl);
      }
    }
      // current
    std::cout << *El;
      // successors
    for (auto& rtEl : el->right) {
      if (rtEL->runID != runID) {
        traverse(rtEl);
      }
    }
  }
}