Reputation: 361
I have written below code. However I am not sure if I have inserted my tree correctly. The code compiles sucessfully but I don't get the DFS traversed array in the output. Can someone tell me where I am going wrong ?
The input tree is below but please let me know if I have made the correct calls in the main function ? As my output is coming - [a b c d e f g h i j k]. whereas the correct output should be [a b e f i j c d g k h].
A
/ \ \
B C D
/ \ / \
E F G H
/ \ \
I J K
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
string name;
vector <Node *> children;
Node(string name)
{
this->name = name;
}
//O(v+e) time | O(v) space
vector <string> depthFirstSearch(vector<string> *array)
{
array->push_back(this->name);
for(size_t i = 0; i < this->children.size(); i++)
children[i]->depthFirstSearch(array);
return *array;
}
Node *addChild(string name)
{
Node *child = new Node(name);
children.push_back(child);
return this;
}
};
int main()
{
Node n1("a");
n1.addChild("b");
n1.addChild("c");
n1.addChild("d");
n1.children[0]->addChild("e");
n1.children[0]->addChild("f");
n1.children[0]->children[1]->addChild("i");
n1.children[0]->children[1]->addChild("j");
n1.children[2]->addChild("g");
n1.children[2]->addChild("h");
n1.children[2]->children[0]->addChild("k");
vector <string> array;
n1.depthFirstSearch(&array);
for (size_t i = 0; i< array.size(); i++)
cout<<array[i]<<' ';
}
Note - Thanks for the explanation , but I made some edits in the way I constructed the tree in the main function and continued using return this statement and it worked.
Upvotes: 0
Views: 462
Reputation: 20141
The error is actually simple but not where it might be expected.
The Node::addChild()
returns this
:
Node *addChild(string name)
{
Node *child = new Node(name);
children.push_back(child);
return this; // <-- OUCH!
}
So, when used in main()
:
Node n1("a");
Node *n2 = n1.addChild("b"); // => n2 = &n1;
n1.addChild("c");
Node *n4 = n1.addChild("d"); // => n4 = &n1;
n2->addChild("e");
Node *n3 = n2->addChild("f"); // => n3 = n2 = &n1;
n3->addChild("i");
n3->addChild("j");
Node *n5 = n4->addChild("g"); // => n5 = n4 = &n1;
n4->addChild("h");
n5->addChild("k");
So, the tree actually does not get the expected shape but rather something like:
A________________
/ \ \ \ \ \ \ \ \ \
B C D E F G H I J K
for what the current output of OP is fully correct.
The fix is simple:
Node *addChild(string name)
{
Node *child = new Node(name);
children.push_back(child);
return child;
}
Output:
a b e f i j c d g k h
OP insisted in that Node::addChild()
has to return this;
and asked for another way to circumvent the issue. I tried to convince OP that return child;
would make more sense than return this;
.
Actually, I intuitively expected that Node::addChild()
would return the the created child which costed me some extra debugging to find the actual bug. :-)
Concerning
the way I have constructed my tree in the main function - is it the right way or there can be more efficient way of doing that
I personally find the code in main()
not that bad as it is.
However, there are often more than one way to Rome.
So, here is just another idea:
A second constructor to construct child nodes explicitly:
Node(Node &parent, string name): Node(name)
{
parent.children.push_back(this);
}
which allows to write the tree init. in main()
like this:
Node nA("a");
Node nB(nA, "b");
Node nC(nA, "c");
Node nD(nA, "d");
Node nE(nB, "e");
Node nF(nB, "f");
Node nI(nF, "i");
Node nJ(nF, "j");
Node nG(nD, "g");
Node nH(nD, "h");
Node nK(nG, "k");
(Node::addChild()
is even not used/needed in this case.)
Output:
a b e f i j c d g k h
Upvotes: 1