树节点迷失了

时间:2016-08-19 17:57:35

标签: c++ tree

所以我正在尝试进行在线作业(这不是为了学分,我是通过课程自学)而且我对发生的事情非常困惑。

我们获得了2行输入。第一行是树中的顶点数。第二行列出父节点的所有节点,其中-1表示它是根。

例如,给出以下输入:

5

4 -1 4 1 1

第一行表示总共有5个节点。第二行表示节点0是节点4(节点1)的子节点 是根,节点2是节点4的子节点,节点3是节点1的子节点,节点4是节点1的子节点。

现在我只是试图读入输入并将其存储在树形结构中。

#include <iostream>
#include <vector>


using namespace std;

struct Node{
    int key;
    vector<Node*> children;
};


void display(Node* root){
    cout << "My Value is " << root->key << endl;
    cout << "My children are ";
    for (int i = 0; i < root->children.size(); i++){
        cout << root->children[i]->key << " ";
    }
    cout << endl;
    for (int i = 0; i < root->children.size(); i++){
        display(root->children[i]);         //call display on all children
    }
    cout << endl;
}

int main(){

    Node* root = NULL;
    int numOfNodes;
    cin >> numOfNodes;

    int input;
    vector<int> parents;
    for(int i = 0; i < numOfNodes; i++){
        cin >> input;
        parents.push_back(input);
    }

    for(int i = 0; i < parents.size(); i++){
        Node *newNode = new Node();
        newNode->key = i;
        if(parents[i] == -1){ //root node is indicated with a -1 in input
            root = newNode;
        }
        for (int j = 0; j < parents.size(); j++){
            if(parents[j] == i){
                Node *childNode = new Node();
                childNode->key = j;
                newNode->children.push_back(childNode);
                cout << "value " << newNode->key << " is now a parent of " << childNode->key << endl;
                //delete childNode;
            }
        }
    }
    display(root);

    return 0;
}

我在显示功能中添加了以查看我是否正确存储树,这就是我丢失的地方。我添加的印刷语句似乎有冲突。在main中,每当我添加一个childNode时我都添加了一个cout,但是当我的程序进入display函数时,看起来childNodes缺少了根节点子节点的异常。这是我输出的一个示例。

./treeheight
5
4 -1 4 1 1
value 1 is now a parent of 3
value 1 is now a parent of 4
value 4 is now a parent of 0
value 4 is now a parent of 2
My Value is 1
My children are 3 4 
My Value is 3
My children are 

My Value is 4
My children are 

似乎在main中创建树的工作正如我所希望的那样但是当我尝试在显示中引用那些相同的节点时出现了一些我不理解的错误。我原以为显示中的输出会读取

My Value is 1
My children are 3 4 
My Value is 3
My children are 

My Value is 4
My children are 2 0

如果有人能够对这里发生的事情有所了解,我将非常感激。

2 个答案:

答案 0 :(得分:3)

i == 2时,您创建一个节点Node(1),内部循环找到两个孩子Node(3)Node(4)。这为您提供了以下结构:

            Node(1)
             /   \
        Node(3) Node(4)

然后将此结构保存在root中。所以这就得救了。然后,在i == 3时,您创建一个新节点Node(3)。注意:这与Node(3)中以{1}}开始的树中的节点root不同。它们具有相同的密钥,但它们是两个完全不同的节点。

同样的事情发生在i == 4时。您创建一个新节点Node(4),它有两个子节点。但这与树中的节点不同。它是new节点。并且由于您不会将子节点Node(0)Node(1)保存到新节点,因此会删除此节点。

所以最后,你只有root节点及其两个孩子。

对于解决方案:您必须将每个节点存储在某个位置。不要扔掉它们。当你已经在某个地方创建新节点时,不要重新创建新节点。例如,您可以使用初始for循环创建所有节点,并将它们保存在临时向量中。然后,将指针复制到子矢量。

答案 1 :(得分:2)

Coursera rock!

分配节点并同时连接它们会使您的算法混乱。我将两个任务分开,结果似乎按预期工作。这通常是一个很好的设计模式,单独的任务,并且各自独立完成。

错误检查有限,因此垃圾输入可能会导致崩溃。

#include <iostream>
#include <vector>


using namespace std;

struct Node{
    int key;
    vector<Node*> children;
};


void display(Node* root){
    cout << "My Value is " << root->key << endl;
    cout << "My children are ";
    for (int i = 0; i < root->children.size(); i++){
        cout << root->children[i]->key << " ";
    }
    cout << endl;
    for (int i = 0; i < root->children.size(); i++){
        display(root->children[i]);         //call display on all children
    }
    cout << endl;
}

int main(){

    Node* root = NULL;
    int numOfNodes;
    vector<Node> nodes;
    cin >> numOfNodes;

    int input;
    vector<int> parents;
    for(int i = 0; i < numOfNodes; i++){
        cin >> input;
        parents.push_back(input);
    }

    for(int i = 0; i < parents.size(); i++)  // make a vector of nodes for storage
       nodes.push_back(Node());

    for(int i = 0; i < parents.size(); i++){
        nodes[i].key = i;  // set the key on each
        if(parents[i] == -1){ //root node is indicated with a -1 in input
            root = &nodes[i];
        }
        else
        {
           nodes[parents[i]].children.push_back(&nodes[i]);  // set parent
        }
    }
    display(root);

    return 0;
}