Depth First Search in C++

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












After studying from Introduction to Algorithm and taking help from internet I have written a program. I don't know much about C++11. Please help me to optimize this program with better functions and better runtime.



Note: I have used adjacency matrix instead of adjacency list and I don't know whether I have used it in correct way.



#include <iostream>
#include <vector>

class Graph

int V; //no of Vertices
enum class Color WHITE, GRAY, BLACK ;

struct Vertex

char id;
Color color;
Vertex(char c, Color clr) : id(c), color(clr)
;
std::vector< std::vector<int> > adjMatrix; //adjacency Matrix
std::vector<Vertex> vertices;

public:
Graph(int);
void addEdge(int, int);
void DFS(int);
;

Graph::Graph(int v)

V = v;
adjMatrix.resize(V, std::vector<int>(V));
for(int i = 0; i < V; i++)

vertices.push_back( Vertex('A'+i, Color::WHITE));
for(int j = 0; j < V; j++)

adjMatrix[i][j] = 0;




void Graph::addEdge(int a, int b)

adjMatrix[a][b] = 1;


void Graph::DFS(int u)

vertices[u].color = Color::GRAY;
std::cout << vertices[u].id <<" ";

for(int i = u; i < V; i++)

for(int j = 0; j < V; j++)

if(adjMatrix[i][j] == 1)

if(vertices[j].color == Color::WHITE)
DFS(j);



vertices[u].color = Color::BLACK; //blacken u, it is finished


int main()

Graph grp(4);
grp.addEdge(0, 1);
grp.addEdge(1, 2);
grp.addEdge(2, 3);
grp.addEdge(2, 1);
grp.addEdge(0, 3);

grp.DFS(2);
return 0;







share|improve this question



























    up vote
    1
    down vote

    favorite












    After studying from Introduction to Algorithm and taking help from internet I have written a program. I don't know much about C++11. Please help me to optimize this program with better functions and better runtime.



    Note: I have used adjacency matrix instead of adjacency list and I don't know whether I have used it in correct way.



    #include <iostream>
    #include <vector>

    class Graph

    int V; //no of Vertices
    enum class Color WHITE, GRAY, BLACK ;

    struct Vertex

    char id;
    Color color;
    Vertex(char c, Color clr) : id(c), color(clr)
    ;
    std::vector< std::vector<int> > adjMatrix; //adjacency Matrix
    std::vector<Vertex> vertices;

    public:
    Graph(int);
    void addEdge(int, int);
    void DFS(int);
    ;

    Graph::Graph(int v)

    V = v;
    adjMatrix.resize(V, std::vector<int>(V));
    for(int i = 0; i < V; i++)

    vertices.push_back( Vertex('A'+i, Color::WHITE));
    for(int j = 0; j < V; j++)

    adjMatrix[i][j] = 0;




    void Graph::addEdge(int a, int b)

    adjMatrix[a][b] = 1;


    void Graph::DFS(int u)

    vertices[u].color = Color::GRAY;
    std::cout << vertices[u].id <<" ";

    for(int i = u; i < V; i++)

    for(int j = 0; j < V; j++)

    if(adjMatrix[i][j] == 1)

    if(vertices[j].color == Color::WHITE)
    DFS(j);



    vertices[u].color = Color::BLACK; //blacken u, it is finished


    int main()

    Graph grp(4);
    grp.addEdge(0, 1);
    grp.addEdge(1, 2);
    grp.addEdge(2, 3);
    grp.addEdge(2, 1);
    grp.addEdge(0, 3);

    grp.DFS(2);
    return 0;







    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      After studying from Introduction to Algorithm and taking help from internet I have written a program. I don't know much about C++11. Please help me to optimize this program with better functions and better runtime.



      Note: I have used adjacency matrix instead of adjacency list and I don't know whether I have used it in correct way.



      #include <iostream>
      #include <vector>

      class Graph

      int V; //no of Vertices
      enum class Color WHITE, GRAY, BLACK ;

      struct Vertex

      char id;
      Color color;
      Vertex(char c, Color clr) : id(c), color(clr)
      ;
      std::vector< std::vector<int> > adjMatrix; //adjacency Matrix
      std::vector<Vertex> vertices;

      public:
      Graph(int);
      void addEdge(int, int);
      void DFS(int);
      ;

      Graph::Graph(int v)

      V = v;
      adjMatrix.resize(V, std::vector<int>(V));
      for(int i = 0; i < V; i++)

      vertices.push_back( Vertex('A'+i, Color::WHITE));
      for(int j = 0; j < V; j++)

      adjMatrix[i][j] = 0;




      void Graph::addEdge(int a, int b)

      adjMatrix[a][b] = 1;


      void Graph::DFS(int u)

      vertices[u].color = Color::GRAY;
      std::cout << vertices[u].id <<" ";

      for(int i = u; i < V; i++)

      for(int j = 0; j < V; j++)

      if(adjMatrix[i][j] == 1)

      if(vertices[j].color == Color::WHITE)
      DFS(j);



      vertices[u].color = Color::BLACK; //blacken u, it is finished


      int main()

      Graph grp(4);
      grp.addEdge(0, 1);
      grp.addEdge(1, 2);
      grp.addEdge(2, 3);
      grp.addEdge(2, 1);
      grp.addEdge(0, 3);

      grp.DFS(2);
      return 0;







      share|improve this question













      After studying from Introduction to Algorithm and taking help from internet I have written a program. I don't know much about C++11. Please help me to optimize this program with better functions and better runtime.



      Note: I have used adjacency matrix instead of adjacency list and I don't know whether I have used it in correct way.



      #include <iostream>
      #include <vector>

      class Graph

      int V; //no of Vertices
      enum class Color WHITE, GRAY, BLACK ;

      struct Vertex

      char id;
      Color color;
      Vertex(char c, Color clr) : id(c), color(clr)
      ;
      std::vector< std::vector<int> > adjMatrix; //adjacency Matrix
      std::vector<Vertex> vertices;

      public:
      Graph(int);
      void addEdge(int, int);
      void DFS(int);
      ;

      Graph::Graph(int v)

      V = v;
      adjMatrix.resize(V, std::vector<int>(V));
      for(int i = 0; i < V; i++)

      vertices.push_back( Vertex('A'+i, Color::WHITE));
      for(int j = 0; j < V; j++)

      adjMatrix[i][j] = 0;




      void Graph::addEdge(int a, int b)

      adjMatrix[a][b] = 1;


      void Graph::DFS(int u)

      vertices[u].color = Color::GRAY;
      std::cout << vertices[u].id <<" ";

      for(int i = u; i < V; i++)

      for(int j = 0; j < V; j++)

      if(adjMatrix[i][j] == 1)

      if(vertices[j].color == Color::WHITE)
      DFS(j);



      vertices[u].color = Color::BLACK; //blacken u, it is finished


      int main()

      Graph grp(4);
      grp.addEdge(0, 1);
      grp.addEdge(1, 2);
      grp.addEdge(2, 3);
      grp.addEdge(2, 1);
      grp.addEdge(0, 3);

      grp.DFS(2);
      return 0;









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jan 7 at 14:11









      Billal BEGUERADJ

      1




      1









      asked Jan 6 at 16:16









      coder

      916425




      916425




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Reduce Complexity, Follow SRP

          In both this question and the Binary Search Tree in C++ struct definitions have been embedded within the class definitions. This goes against good object oriented programming principles, specifically the Single Responsibility Principle. One of the basics of object oriented programing is to be able to reuse objects in multiple programs. Each object should be defined separately so that one builds up a library of objects/files that can be reused. In C++ a struct is a class where all members are public, since they are classes they should be defined on their own.



          In this program it would be better if there be three header files and possibly two source files, one for Graph and one for Vertex. Vertex may not need a C++ source file since it is fairly simple. The color class also deserves it's own header file. In the Binary Search Tree question Node should be defined separately from BinaryTree.



          You might also want to look into SOLID programming principles (the S is the Single Responsibility Principle).



          The Single Responsibility Principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.




          Robert C. Martin expresses the principle as follows:
          A class should have only one reason to change.




          While this is primarily targeted at classes in object oriented languages it applies to functions and subroutines well.



          Inconsistent Indentation

          The contents of the struct Vertex are not indented and they should be.



          Inconsistent Naming Conventions

          The naming of variables and functions is inconsistent, there are well named functions and variables such as adjMatrix, addEdge(), id and color, and then there are names such as V and DFS(). It might be better to name V as verticyCount or maxVirtecies and DFS() as depthFirstSearch().



          Inconsistent Initialization in Constructors

          The constructor for Vertex uses C++ initialization for it's variables, but the Graph constructor does. It might be better if Graph was written as :



          Graph::Graph(int v)
          : Vv

          adjMatrix.resize(V, std::vector<int>(V));
          for(int i = 0; i < V; i++)

          vertices.push_back( Vertex('A'+i, Color::WHITE));
          for(int j = 0; j < V; j++)

          adjMatrix[i][j] = 0;





          Please note that the call to std::vector.resize() is not necessary in this constructor. C++ implementations generally include a base allocation of memory for constructors and as the vector grows or shrinks, resize will be called implicitly. Also note that operators such as + should be separated by spaces to make the code more readable.



           vertices.push_back(Vertex('A' + i, Color::WHITE));


          In the initialization of Vertex, braces should be preferred to parens:



           Vertex(char c, Color clr) : idc, colorclr 


          The use of parens is supported for backwards compatibility on some C++ compilers, however, it is obsolete.



          The two other answers concerns about the DFS() function are valid, you can find a fast working Breath First Search recursive implementation in the KnightMovesImplementation.cpp file, function bool KnightMovesImplementation::CalculatePath(KMMove CurrentMove) in this question.






          share|improve this answer

















          • 1




            Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
            – 1201ProgramAlarm
            Jan 7 at 17:32










          • @1201ProgramAlarm thanks, I learn something new every day.
            – pacmaninbw
            Jan 7 at 17:37






          • 1




            I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
            – coder
            Jan 8 at 8:11


















          up vote
          2
          down vote













          When you add an edge a -> b you do not add a corresponding b -> a. This makes your Graph a directed graph. Was that your intent?



          You have no mechanism for setting all the colors. You need to either rotate color settings (change the values of black/white/grey) or add some kind of "set-everything-to-white" method. Otherwise, you can only DFS one time. ;-)



          You may wish to use std::vector<bool> instead of <int> in order to save space. For a 4x4 matrix this won't be a problem, but if you get called on to use a 64k x 64k matrix, space will be an issue.



          Your DFS algorithm seems wrong. I don't understand why there are two loops plus recursion. With recursion and a matrix, you only need one loop.



          Here's an example I found on a different post:



           5
          /
          7 3
          / /
          4 1 6 2


          What do you think the output sequence should be, starting from 5?



          I think it would look like: 5, 3, 2, 6, 7, 1, 4 since you scan from 0..size in your adjacency matrix. (That is, 5 would find 3 before 7, etc.)






          share|improve this answer





















          • I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
            – coder
            Jan 7 at 6:17










          • @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
            – Austin Hastings
            Jan 7 at 19:21

















          up vote
          2
          down vote













          void dfs(int node) 
          if (visit[node]==1) return;
          if (visit[node]==2)
          b=0;
          return;

          visit[node] = 2;
          for (int i = 0; i < v[node].size(); i++)dfs(v[node][i]);
          ans.push_back(node);
          visit[node]=1;



          Here is a sample dfs code. I guess you really shouldn't loop so many times in your answer. Logic here is basically what Austin mentioned above.






          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184456%2fdepth-first-search-in-c%23new-answer', 'question_page');

            );

            Post as a guest






























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote



            accepted










            Reduce Complexity, Follow SRP

            In both this question and the Binary Search Tree in C++ struct definitions have been embedded within the class definitions. This goes against good object oriented programming principles, specifically the Single Responsibility Principle. One of the basics of object oriented programing is to be able to reuse objects in multiple programs. Each object should be defined separately so that one builds up a library of objects/files that can be reused. In C++ a struct is a class where all members are public, since they are classes they should be defined on their own.



            In this program it would be better if there be three header files and possibly two source files, one for Graph and one for Vertex. Vertex may not need a C++ source file since it is fairly simple. The color class also deserves it's own header file. In the Binary Search Tree question Node should be defined separately from BinaryTree.



            You might also want to look into SOLID programming principles (the S is the Single Responsibility Principle).



            The Single Responsibility Principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.




            Robert C. Martin expresses the principle as follows:
            A class should have only one reason to change.




            While this is primarily targeted at classes in object oriented languages it applies to functions and subroutines well.



            Inconsistent Indentation

            The contents of the struct Vertex are not indented and they should be.



            Inconsistent Naming Conventions

            The naming of variables and functions is inconsistent, there are well named functions and variables such as adjMatrix, addEdge(), id and color, and then there are names such as V and DFS(). It might be better to name V as verticyCount or maxVirtecies and DFS() as depthFirstSearch().



            Inconsistent Initialization in Constructors

            The constructor for Vertex uses C++ initialization for it's variables, but the Graph constructor does. It might be better if Graph was written as :



            Graph::Graph(int v)
            : Vv

            adjMatrix.resize(V, std::vector<int>(V));
            for(int i = 0; i < V; i++)

            vertices.push_back( Vertex('A'+i, Color::WHITE));
            for(int j = 0; j < V; j++)

            adjMatrix[i][j] = 0;





            Please note that the call to std::vector.resize() is not necessary in this constructor. C++ implementations generally include a base allocation of memory for constructors and as the vector grows or shrinks, resize will be called implicitly. Also note that operators such as + should be separated by spaces to make the code more readable.



             vertices.push_back(Vertex('A' + i, Color::WHITE));


            In the initialization of Vertex, braces should be preferred to parens:



             Vertex(char c, Color clr) : idc, colorclr 


            The use of parens is supported for backwards compatibility on some C++ compilers, however, it is obsolete.



            The two other answers concerns about the DFS() function are valid, you can find a fast working Breath First Search recursive implementation in the KnightMovesImplementation.cpp file, function bool KnightMovesImplementation::CalculatePath(KMMove CurrentMove) in this question.






            share|improve this answer

















            • 1




              Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
              – 1201ProgramAlarm
              Jan 7 at 17:32










            • @1201ProgramAlarm thanks, I learn something new every day.
              – pacmaninbw
              Jan 7 at 17:37






            • 1




              I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
              – coder
              Jan 8 at 8:11















            up vote
            3
            down vote



            accepted










            Reduce Complexity, Follow SRP

            In both this question and the Binary Search Tree in C++ struct definitions have been embedded within the class definitions. This goes against good object oriented programming principles, specifically the Single Responsibility Principle. One of the basics of object oriented programing is to be able to reuse objects in multiple programs. Each object should be defined separately so that one builds up a library of objects/files that can be reused. In C++ a struct is a class where all members are public, since they are classes they should be defined on their own.



            In this program it would be better if there be three header files and possibly two source files, one for Graph and one for Vertex. Vertex may not need a C++ source file since it is fairly simple. The color class also deserves it's own header file. In the Binary Search Tree question Node should be defined separately from BinaryTree.



            You might also want to look into SOLID programming principles (the S is the Single Responsibility Principle).



            The Single Responsibility Principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.




            Robert C. Martin expresses the principle as follows:
            A class should have only one reason to change.




            While this is primarily targeted at classes in object oriented languages it applies to functions and subroutines well.



            Inconsistent Indentation

            The contents of the struct Vertex are not indented and they should be.



            Inconsistent Naming Conventions

            The naming of variables and functions is inconsistent, there are well named functions and variables such as adjMatrix, addEdge(), id and color, and then there are names such as V and DFS(). It might be better to name V as verticyCount or maxVirtecies and DFS() as depthFirstSearch().



            Inconsistent Initialization in Constructors

            The constructor for Vertex uses C++ initialization for it's variables, but the Graph constructor does. It might be better if Graph was written as :



            Graph::Graph(int v)
            : Vv

            adjMatrix.resize(V, std::vector<int>(V));
            for(int i = 0; i < V; i++)

            vertices.push_back( Vertex('A'+i, Color::WHITE));
            for(int j = 0; j < V; j++)

            adjMatrix[i][j] = 0;





            Please note that the call to std::vector.resize() is not necessary in this constructor. C++ implementations generally include a base allocation of memory for constructors and as the vector grows or shrinks, resize will be called implicitly. Also note that operators such as + should be separated by spaces to make the code more readable.



             vertices.push_back(Vertex('A' + i, Color::WHITE));


            In the initialization of Vertex, braces should be preferred to parens:



             Vertex(char c, Color clr) : idc, colorclr 


            The use of parens is supported for backwards compatibility on some C++ compilers, however, it is obsolete.



            The two other answers concerns about the DFS() function are valid, you can find a fast working Breath First Search recursive implementation in the KnightMovesImplementation.cpp file, function bool KnightMovesImplementation::CalculatePath(KMMove CurrentMove) in this question.






            share|improve this answer

















            • 1




              Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
              – 1201ProgramAlarm
              Jan 7 at 17:32










            • @1201ProgramAlarm thanks, I learn something new every day.
              – pacmaninbw
              Jan 7 at 17:37






            • 1




              I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
              – coder
              Jan 8 at 8:11













            up vote
            3
            down vote



            accepted







            up vote
            3
            down vote



            accepted






            Reduce Complexity, Follow SRP

            In both this question and the Binary Search Tree in C++ struct definitions have been embedded within the class definitions. This goes against good object oriented programming principles, specifically the Single Responsibility Principle. One of the basics of object oriented programing is to be able to reuse objects in multiple programs. Each object should be defined separately so that one builds up a library of objects/files that can be reused. In C++ a struct is a class where all members are public, since they are classes they should be defined on their own.



            In this program it would be better if there be three header files and possibly two source files, one for Graph and one for Vertex. Vertex may not need a C++ source file since it is fairly simple. The color class also deserves it's own header file. In the Binary Search Tree question Node should be defined separately from BinaryTree.



            You might also want to look into SOLID programming principles (the S is the Single Responsibility Principle).



            The Single Responsibility Principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.




            Robert C. Martin expresses the principle as follows:
            A class should have only one reason to change.




            While this is primarily targeted at classes in object oriented languages it applies to functions and subroutines well.



            Inconsistent Indentation

            The contents of the struct Vertex are not indented and they should be.



            Inconsistent Naming Conventions

            The naming of variables and functions is inconsistent, there are well named functions and variables such as adjMatrix, addEdge(), id and color, and then there are names such as V and DFS(). It might be better to name V as verticyCount or maxVirtecies and DFS() as depthFirstSearch().



            Inconsistent Initialization in Constructors

            The constructor for Vertex uses C++ initialization for it's variables, but the Graph constructor does. It might be better if Graph was written as :



            Graph::Graph(int v)
            : Vv

            adjMatrix.resize(V, std::vector<int>(V));
            for(int i = 0; i < V; i++)

            vertices.push_back( Vertex('A'+i, Color::WHITE));
            for(int j = 0; j < V; j++)

            adjMatrix[i][j] = 0;





            Please note that the call to std::vector.resize() is not necessary in this constructor. C++ implementations generally include a base allocation of memory for constructors and as the vector grows or shrinks, resize will be called implicitly. Also note that operators such as + should be separated by spaces to make the code more readable.



             vertices.push_back(Vertex('A' + i, Color::WHITE));


            In the initialization of Vertex, braces should be preferred to parens:



             Vertex(char c, Color clr) : idc, colorclr 


            The use of parens is supported for backwards compatibility on some C++ compilers, however, it is obsolete.



            The two other answers concerns about the DFS() function are valid, you can find a fast working Breath First Search recursive implementation in the KnightMovesImplementation.cpp file, function bool KnightMovesImplementation::CalculatePath(KMMove CurrentMove) in this question.






            share|improve this answer













            Reduce Complexity, Follow SRP

            In both this question and the Binary Search Tree in C++ struct definitions have been embedded within the class definitions. This goes against good object oriented programming principles, specifically the Single Responsibility Principle. One of the basics of object oriented programing is to be able to reuse objects in multiple programs. Each object should be defined separately so that one builds up a library of objects/files that can be reused. In C++ a struct is a class where all members are public, since they are classes they should be defined on their own.



            In this program it would be better if there be three header files and possibly two source files, one for Graph and one for Vertex. Vertex may not need a C++ source file since it is fairly simple. The color class also deserves it's own header file. In the Binary Search Tree question Node should be defined separately from BinaryTree.



            You might also want to look into SOLID programming principles (the S is the Single Responsibility Principle).



            The Single Responsibility Principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.




            Robert C. Martin expresses the principle as follows:
            A class should have only one reason to change.




            While this is primarily targeted at classes in object oriented languages it applies to functions and subroutines well.



            Inconsistent Indentation

            The contents of the struct Vertex are not indented and they should be.



            Inconsistent Naming Conventions

            The naming of variables and functions is inconsistent, there are well named functions and variables such as adjMatrix, addEdge(), id and color, and then there are names such as V and DFS(). It might be better to name V as verticyCount or maxVirtecies and DFS() as depthFirstSearch().



            Inconsistent Initialization in Constructors

            The constructor for Vertex uses C++ initialization for it's variables, but the Graph constructor does. It might be better if Graph was written as :



            Graph::Graph(int v)
            : Vv

            adjMatrix.resize(V, std::vector<int>(V));
            for(int i = 0; i < V; i++)

            vertices.push_back( Vertex('A'+i, Color::WHITE));
            for(int j = 0; j < V; j++)

            adjMatrix[i][j] = 0;





            Please note that the call to std::vector.resize() is not necessary in this constructor. C++ implementations generally include a base allocation of memory for constructors and as the vector grows or shrinks, resize will be called implicitly. Also note that operators such as + should be separated by spaces to make the code more readable.



             vertices.push_back(Vertex('A' + i, Color::WHITE));


            In the initialization of Vertex, braces should be preferred to parens:



             Vertex(char c, Color clr) : idc, colorclr 


            The use of parens is supported for backwards compatibility on some C++ compilers, however, it is obsolete.



            The two other answers concerns about the DFS() function are valid, you can find a fast working Breath First Search recursive implementation in the KnightMovesImplementation.cpp file, function bool KnightMovesImplementation::CalculatePath(KMMove CurrentMove) in this question.







            share|improve this answer













            share|improve this answer



            share|improve this answer











            answered Jan 7 at 16:57









            pacmaninbw

            4,99321436




            4,99321436







            • 1




              Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
              – 1201ProgramAlarm
              Jan 7 at 17:32










            • @1201ProgramAlarm thanks, I learn something new every day.
              – pacmaninbw
              Jan 7 at 17:37






            • 1




              I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
              – coder
              Jan 8 at 8:11













            • 1




              Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
              – 1201ProgramAlarm
              Jan 7 at 17:32










            • @1201ProgramAlarm thanks, I learn something new every day.
              – pacmaninbw
              Jan 7 at 17:37






            • 1




              I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
              – coder
              Jan 8 at 8:11








            1




            1




            Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
            – 1201ProgramAlarm
            Jan 7 at 17:32




            Graph::Graph(int v): V(v), adjMatrix(v, std::vector<int>(v)) then you can get rid of the resize. And the j loop can go away, too, since the resize zero-initialized all those ints. if v is potentially large, I'd include a vertices.reserve call before the i loop. The use of parenthesis in initializers is part of the language, so all conforming compilers must support it.
            – 1201ProgramAlarm
            Jan 7 at 17:32












            @1201ProgramAlarm thanks, I learn something new every day.
            – pacmaninbw
            Jan 7 at 17:37




            @1201ProgramAlarm thanks, I learn something new every day.
            – pacmaninbw
            Jan 7 at 17:37




            1




            1




            I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
            – coder
            Jan 8 at 8:11





            I understood SRP that I have to design class which is responsible for specific task but I am unable to write code which follows SRP. Can you write it? I don't know advanced C++ so I didn't understand KnightMovesImplementation.cpp
            – coder
            Jan 8 at 8:11













            up vote
            2
            down vote













            When you add an edge a -> b you do not add a corresponding b -> a. This makes your Graph a directed graph. Was that your intent?



            You have no mechanism for setting all the colors. You need to either rotate color settings (change the values of black/white/grey) or add some kind of "set-everything-to-white" method. Otherwise, you can only DFS one time. ;-)



            You may wish to use std::vector<bool> instead of <int> in order to save space. For a 4x4 matrix this won't be a problem, but if you get called on to use a 64k x 64k matrix, space will be an issue.



            Your DFS algorithm seems wrong. I don't understand why there are two loops plus recursion. With recursion and a matrix, you only need one loop.



            Here's an example I found on a different post:



             5
            /
            7 3
            / /
            4 1 6 2


            What do you think the output sequence should be, starting from 5?



            I think it would look like: 5, 3, 2, 6, 7, 1, 4 since you scan from 0..size in your adjacency matrix. (That is, 5 would find 3 before 7, etc.)






            share|improve this answer





















            • I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
              – coder
              Jan 7 at 6:17










            • @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
              – Austin Hastings
              Jan 7 at 19:21














            up vote
            2
            down vote













            When you add an edge a -> b you do not add a corresponding b -> a. This makes your Graph a directed graph. Was that your intent?



            You have no mechanism for setting all the colors. You need to either rotate color settings (change the values of black/white/grey) or add some kind of "set-everything-to-white" method. Otherwise, you can only DFS one time. ;-)



            You may wish to use std::vector<bool> instead of <int> in order to save space. For a 4x4 matrix this won't be a problem, but if you get called on to use a 64k x 64k matrix, space will be an issue.



            Your DFS algorithm seems wrong. I don't understand why there are two loops plus recursion. With recursion and a matrix, you only need one loop.



            Here's an example I found on a different post:



             5
            /
            7 3
            / /
            4 1 6 2


            What do you think the output sequence should be, starting from 5?



            I think it would look like: 5, 3, 2, 6, 7, 1, 4 since you scan from 0..size in your adjacency matrix. (That is, 5 would find 3 before 7, etc.)






            share|improve this answer





















            • I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
              – coder
              Jan 7 at 6:17










            • @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
              – Austin Hastings
              Jan 7 at 19:21












            up vote
            2
            down vote










            up vote
            2
            down vote









            When you add an edge a -> b you do not add a corresponding b -> a. This makes your Graph a directed graph. Was that your intent?



            You have no mechanism for setting all the colors. You need to either rotate color settings (change the values of black/white/grey) or add some kind of "set-everything-to-white" method. Otherwise, you can only DFS one time. ;-)



            You may wish to use std::vector<bool> instead of <int> in order to save space. For a 4x4 matrix this won't be a problem, but if you get called on to use a 64k x 64k matrix, space will be an issue.



            Your DFS algorithm seems wrong. I don't understand why there are two loops plus recursion. With recursion and a matrix, you only need one loop.



            Here's an example I found on a different post:



             5
            /
            7 3
            / /
            4 1 6 2


            What do you think the output sequence should be, starting from 5?



            I think it would look like: 5, 3, 2, 6, 7, 1, 4 since you scan from 0..size in your adjacency matrix. (That is, 5 would find 3 before 7, etc.)






            share|improve this answer













            When you add an edge a -> b you do not add a corresponding b -> a. This makes your Graph a directed graph. Was that your intent?



            You have no mechanism for setting all the colors. You need to either rotate color settings (change the values of black/white/grey) or add some kind of "set-everything-to-white" method. Otherwise, you can only DFS one time. ;-)



            You may wish to use std::vector<bool> instead of <int> in order to save space. For a 4x4 matrix this won't be a problem, but if you get called on to use a 64k x 64k matrix, space will be an issue.



            Your DFS algorithm seems wrong. I don't understand why there are two loops plus recursion. With recursion and a matrix, you only need one loop.



            Here's an example I found on a different post:



             5
            /
            7 3
            / /
            4 1 6 2


            What do you think the output sequence should be, starting from 5?



            I think it would look like: 5, 3, 2, 6, 7, 1, 4 since you scan from 0..size in your adjacency matrix. (That is, 5 would find 3 before 7, etc.)







            share|improve this answer













            share|improve this answer



            share|improve this answer











            answered Jan 6 at 17:19









            Austin Hastings

            6,1591130




            6,1591130











            • I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
              – coder
              Jan 7 at 6:17










            • @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
              – Austin Hastings
              Jan 7 at 19:21
















            • I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
              – coder
              Jan 7 at 6:17










            • @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
              – Austin Hastings
              Jan 7 at 19:21















            I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
            – coder
            Jan 7 at 6:17




            I think this line vertices.push_back( Vertex('A'+i, Color::WHITE)); set everything to white initially. I have used two loops to know where is 1 in adjacency matrix.
            – coder
            Jan 7 at 6:17












            @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
            – Austin Hastings
            Jan 7 at 19:21




            @coder Yes, you set the colors to white initially. But that means you only get one DFS. After that, you'll need to reset them to white again. For knowing where there is a 1 in the adjacency matrix, remember that you are processing a particular vertex, so you already know one coordinate. You get called with int u as a parameter. So the only question is, what other vertices are linked with u? That means you should need just one loop. (You will recurse into another call to DFS with the new vertex v, so the stack frame is your second "loop".)
            – Austin Hastings
            Jan 7 at 19:21










            up vote
            2
            down vote













            void dfs(int node) 
            if (visit[node]==1) return;
            if (visit[node]==2)
            b=0;
            return;

            visit[node] = 2;
            for (int i = 0; i < v[node].size(); i++)dfs(v[node][i]);
            ans.push_back(node);
            visit[node]=1;



            Here is a sample dfs code. I guess you really shouldn't loop so many times in your answer. Logic here is basically what Austin mentioned above.






            share|improve this answer

























              up vote
              2
              down vote













              void dfs(int node) 
              if (visit[node]==1) return;
              if (visit[node]==2)
              b=0;
              return;

              visit[node] = 2;
              for (int i = 0; i < v[node].size(); i++)dfs(v[node][i]);
              ans.push_back(node);
              visit[node]=1;



              Here is a sample dfs code. I guess you really shouldn't loop so many times in your answer. Logic here is basically what Austin mentioned above.






              share|improve this answer























                up vote
                2
                down vote










                up vote
                2
                down vote









                void dfs(int node) 
                if (visit[node]==1) return;
                if (visit[node]==2)
                b=0;
                return;

                visit[node] = 2;
                for (int i = 0; i < v[node].size(); i++)dfs(v[node][i]);
                ans.push_back(node);
                visit[node]=1;



                Here is a sample dfs code. I guess you really shouldn't loop so many times in your answer. Logic here is basically what Austin mentioned above.






                share|improve this answer













                void dfs(int node) 
                if (visit[node]==1) return;
                if (visit[node]==2)
                b=0;
                return;

                visit[node] = 2;
                for (int i = 0; i < v[node].size(); i++)dfs(v[node][i]);
                ans.push_back(node);
                visit[node]=1;



                Here is a sample dfs code. I guess you really shouldn't loop so many times in your answer. Logic here is basically what Austin mentioned above.







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Jan 7 at 14:16









                QuIcKmAtHs

                140111




                140111






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184456%2fdepth-first-search-in-c%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation