对于以下树,
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;
1)
假设树的深度很大,为了避免堆栈溢出,我们可以在不使用递归的情况下执行DFS吗?
2)
通常,树节点有n个子指针和数据指针(item
),从树上操作的性能方面来看,维护兄弟(nextSibling
)和第一个子节点({的优点是什么? {1}})和父指针(firstChild
)?
答案 0 :(得分:2)
是。通过使用显式数据结构总是可行的 而是根据需要(例如你自己的显式堆栈)来跟踪 你在哪里或你还需要做什么。这样做的原因可能是有限的调用堆栈空间。有些语言支持一种简单的递归方式,称为“tail recursion”,其方式可以自动避免堆栈开销。
修改:在这种特定情况下,您无需跟踪当前节点以外的内容,请参阅下面添加的代码。
“左子/左兄弟”结构的优点是,您可以拥有任意数量的子项,而无需额外的数据结构(例如列表或数组)来管理子项。缺点是你不能直接访问第n个孩子 - 访问第n个孩子是O(n)操作。
给定数据结构的非递归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