简体   繁体   中英

DFS implementation in C++

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 - [ab c defghijk]. whereas the correct output should be [abefij c dgkh].

    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.

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 

Live Demo on coliru


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 

Live Demo on coliru

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM