Left Child Right Sibling tree - Depth First Search - Performance

时间:2016-12-11 18:35:48

标签: c performance data-structures tree

对于以下树,

typedef struct SiblingTreeNode{
  void *item;
  struct SiblingTreeNode *parent;
  struct SiblingTreeNode *firstChild;
  struct SiblingTreeNode *nextSibling;
}SibTreeNode;

typedef struct Tree{
  SibTreeNode *root;
  int size; // number of nodes in tree
}Tree;

enter image description here

1)

假设树的深度很大,为了避免堆栈溢出,我们可以在不使用递归的情况下执行DFS吗?

2)

通常,树节点有n个子指针和数据指针(item),从树上操作的性能方面来看,维护兄弟(nextSibling)和第一个子节点({的优点是什么? {1}})和父指针(firstChild)?

1 个答案:

答案 0 :(得分:2)

  1. 是。通过使用显式数据结构总是可行的 而是根据需要(例如你自己的显式堆栈)来跟踪 你在哪里或你还需要做什么。这样做的原因可能是有限的调用堆栈空间。有些语言支持一种简单的递归方式,称为“tail recursion”,其方式可以自动避免堆栈开销。

    修改:在这种特定情况下,您无需跟踪当前节点以外的内容,请参阅下面添加的代码。

  2. “左子/左兄弟”结构的优点是,您可以拥有任意数量的子项,而无需额外的数据结构(例如列表或数组)来管理子项。缺点是你不能直接访问第n个孩子 - 访问第n个孩子是O(n)操作。

  3. 给定数据结构的非递归DFS:

    void Dfs(Tree* tree) {
      SiblingTreeNode* current = tree.root;
    
      while (current != nullptr) {
    
        visit (current);
    
        if (current->firstChild != nullptr) {
          current = current->firstChild;
        } else if (current->nextSibling != nullptr) {
          current = current->nextSibling;
        } else {
          do {
            current = current->parent;
          } while (current != nullptr && current->nextSibling == nullptr);
          if (current != nullptr) {
             current = current->nextSibling;
          }
        }
      }  // while
    }  // Dfs