我有一个包含next和child的struct节点。
struct Node{
Node *parent;
Node *next;
Node *child;
}
下图显示了树的结构。
我脑子里有一个伪代码,但不确定它是否正确,因为每个节点都有一个孩子,我也需要使用那个孩子进行搜索
while ( root !=NULL)
{
root = root->next;
}
我想访问所有节点。
答案 0 :(得分:2)
我猜你的树看起来像这样:
-> grandma
-> dad
-> me
-> sister
-> niece
-> brother
-> uncle
-> cousin
其中缩进意味着一定程度的祖先。递归函数很简单:
void traverse_rec(const Node *node)
{
if (node) {
process(node);
traverse_rec(node->child);
traverse_rec(node->next);
}
}
这可以重写为循环。如果当前节点有子节点,那就是下一个要访问的节点。否则,你想访问它的兄弟姐妹。但该节点实际上可能没有兄弟姐妹。因为您有到父节点的链接(并且根节点的父节点应该是'NULL),所以您可以回溯树,直到找到要跟随的兄弟节点或节点为NULL
。
void traverse2(const Node *node)
{
while (node) {
puts(node->name);
if (node->child) {
node = node->child;
} else {
while (node && node->next == NULL) {
node = node->parent;
}
if (node) node = node->next;
}
}
}
这比递归函数更复杂,但它可以转换为类似迭代器的代码,在那里得到下一个节点:
const Node *next(const Node *node)
{
if (node == NULL) return NULL;
if (node->child) return node->child;
while (node && node->next == NULL) {
node = node->parent;
}
if (node) return node->next;
return NULL;
}
使用这个“迭代器”,您可以编写如下代码:
for (const Node *p = root; p; p = next(p)) {
puts(p->name);
}
答案 1 :(得分:1)
树按队列转换为班轮列表。并处理班轮列表的每个节点。
伪代码(未经测试):
enqueue(q, root);//queue *q;
while(NULL!=(current_node = dequeue(q))){
//do stuff current_node
if(has_child(current_node)){//unnecessary, include for-loop
for(node = current_node->child; node != NULL; node = node->next){
enqueue(q, node);
}
}
}
答案 2 :(得分:1)
深度优先遍历可以通过以下方式完成,无需父指针:
std::stack<Node*> Q; Q.push(root);
while(!Q.empty())
{ Node* node = Q.top(); Q.pop();
// visit the node, do stuff
if(node->next) Q.push(node->next);
if(node->child) Q.push(node->child);
}
注意它是深度优先的,因为在相同级别的节点之前将访问子节点(如果有的话),这些节点通过 next 指针链接。