我有一个AVL树。每个节点如下所示:
typedef struct {
Node *parent; // the parent node
Node *left; // the node left of this node
Node *right; // the node right of this node
int height; // the height of this node
void *value; // payload
} Node;
是否可以在O(1)空间中使用这些节点迭代AVL树,不带递归,如果是,如何?
如果没有,那么也可以使用具有亚O(n)空间或iff真正必要的O(N)空间的解决方案。
迭代树我的意思是我想要访问每个节点一次,如果可能的话,按顺序(从最左边到mostright节点)。
答案 0 :(得分:6)
如果存储了您访问过的最后一个节点,则可以在迭代器中派生要访问的下一个节点。
该算法为您提供了树的O(1)遍历。你需要对叶子进行一些充实,然后决定你想要决定迭代器应该在哪里进行迭代器(pre / in / post-order),并等待增量。
答案 1 :(得分:0)
只要保留父指针,就可以在给定指向某个节点的指针的情况下获取下一个有序节点。这可以用于从最左边的节点开始迭代树。来自my implementation of AVL tree:
BAVLNode * BAVL_GetNext (const BAVL *o, BAVLNode *n)
{
if (n->link[1]) {
n = n->link[1];
while (n->link[0]) {
n = n->link[0];
}
} else {
while (n->parent && n == n->parent->link[1]) {
n = n->parent;
}
n = n->parent;
}
return n;
}
获取最左边的节点:
BAVLNode * BAVL_GetFirst (const BAVL *o)
{
if (!o->root) {
return NULL;
}
BAVLNode *n = o->root;
while (n->link[0]) {
n = n->link[0];
}
return n;
}
此处,node->link[0]
和node->link[1]
分别是节点的左右子节点,node->parent
是指向父节点的指针(或NULL
表示根节点)。
单个GetNext()操作具有O(logn)时间复杂度。但是,当用于迭代整个树时,您将获得O(n)摊销的时间复杂度。
答案 2 :(得分:0)