【问题标题】:Explain left child right sibling traversal解释左子右兄弟遍历
【发布时间】:2020-03-26 17:26:14
【问题描述】:

我有一个左孩子右兄弟如下:

    10 
*    | 
*    2 -> 3 -> 4 -> 5 
*              |    | 
*              6    7 -> 8 -> 9  */

我想从根节点遍历到最后一个节点,遍历函数如下:

void traverseTree(Node * root) 
{ 
    if (root == NULL) 
        return; 

    while (root) 
    { 
        cout << " " << root->data; 
        if (root->child) 
            traverseTree(root->child); 
        root = root->next; 
    } 
} 

据我了解,如果节点有子节点,则指针指向其子节点,否则指向兄弟节点(下一个)。在这种情况下,当指针指向元素 6 时,它将转到 root->next 元素(即 NULL)。但是,该函数仍然可以打印剩余的元素 (5,7,8,9)。谁能帮我解释一下traverseTree 的工作原理吗?

这是重新创建树的代码:

// CPP program to create a tree with left child 
// right sibling representation. 
#include<bits/stdc++.h> 
using namespace std; 

struct Node 
{ 
    int data; 
    struct Node *next; 
    struct Node *child; 
}; 

// Creating new Node 
Node* newNode(int data) 
{ 
    Node *newNode = new Node; 
    newNode->next = newNode->child = NULL; 
    newNode->data = data; 
    return newNode; 
} 

// Adds a sibling to a list with starting with n 
Node *addSibling(Node *n, int data) 
{ 
    if (n == NULL) 
        return NULL; 

    while (n->next) 
        n = n->next; 

    return (n->next = newNode(data)); 
} 

// Add child Node to a Node 
Node *addChild(Node * n, int data) 
{ 
    if (n == NULL) 
        return NULL; 

    // Check if child list is not empty. 
    if (n->child) 
        return addSibling(n->child, data); 
    else
        return (n->child = newNode(data)); 
} 

// Traverses tree in level order 
void traverseTree(Node * root) 
{ 
    if (root == NULL) 
        return; 

    while (root) 
    { 
        cout << " " << root->data; 
        if (root->child) 
            traverseTree(root->child); 
        root = root->next; 
    } 
} 

//Driver code 

int main() 
{ 
    Node *root = newNode(10); 
    Node *n1 = addChild(root, 2); 
    Node *n2 = addChild(root, 3); 
    Node *n3 = addChild(root, 4); 
    Node *n4 = addChild(n3, 6); 
    Node *n5 = addChild(root, 5); 
    Node *n6 = addChild(n5, 7); 
    Node *n7 = addChild(n5, 8); 
    Node *n8 = addChild(n5, 9); 
    traverseTree(root); 
    return 0; 
} 

【问题讨论】:

    标签: c++ tree


    【解决方案1】:

    执行traverseTree(root-&gt;child) 后,控制流将从下一行继续。你不是从函数返回,只是从这个函数中调用另一个函数。

    void traverseTree(Node * root) 
    { 
        if (root == NULL) 
            return; 
    
        while (root) 
        { 
            cout << " " << root->data; 
            if (root->child) 
                traverseTree(root->child); // First, if child exists, traverse child. No return statement following here.
            root = root->next; // Next, traverse sibling
        } 
    } 
    

    如果您仍然有疑问,最好了解调用函数时的程序流程。

    更新(与问题完全无关):应OP的要求,solution using stack

    void traverseTree(Node * root) 
    { 
        if (root == NULL) 
            return; 
        stack<Node*> s;
        s.push(root);
        while (!s.empty())
        {
            Node* top = s.top();
            cout << " " << top->data;
            s.pop();
            if (top->next) s.push(top->next);
            if (top->child) s.push(top->child);
        }
    } 
    

    【讨论】:

    • 有没有办法在不递归的情况下实现这个?
    • @HaAnTran 是的。使用栈数据结构,所有递归函数都可以不用递归编写。
    • @HaAnTran 是的。这是一个简单的 DFS。您可以使用堆栈来完成。
    • @theWiseBro 是否有我使用堆栈的示例/伪代码?
    • @HaAnTran 接受这个:wandbox.org/permlink/BZzT3ebcs31Wh6u1。也添加到答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2018-06-29
    • 2016-12-20
    相关资源
    最近更新 更多