Add structs to track traversal information in object-graph example
+ Allows Graph member functions to remain const + Easy to pass traversal information around as needed + Update DFS and BFS functions to return traversal information
This commit is contained in:
		
							parent
							
								
									2a36de7c52
								
							
						
					
					
						commit
						64df3419a0
					
				@ -45,7 +45,6 @@ int main (const int argc, const char * argv[])
 | 
				
			|||||||
  // The graph traversed in this example is seen in MIT Intro to Algorithms
 | 
					  // The graph traversed in this example is seen in MIT Intro to Algorithms
 | 
				
			||||||
  // + Chapter 22, Figure 22.3 on BFS
 | 
					  // + Chapter 22, Figure 22.3 on BFS
 | 
				
			||||||
  bfsGraph.BFS(bfsGraph.GetNodeCopy(2));
 | 
					  bfsGraph.BFS(bfsGraph.GetNodeCopy(2));
 | 
				
			||||||
  Node test = bfsGraph.GetNodeCopy(3);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::cout << "\nTesting finding a path between two nodes using BFS...\n";
 | 
					  std::cout << "\nTesting finding a path between two nodes using BFS...\n";
 | 
				
			||||||
  // Test finding a path between two nodes using BFS
 | 
					  // Test finding a path between two nodes using BFS
 | 
				
			||||||
 | 
				
			|||||||
@ -10,23 +10,16 @@
 | 
				
			|||||||
#include "lib-graph.hpp"
 | 
					#include "lib-graph.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graph::BFS(const Node& startNode) const
 | 
					InfoBFS Graph::BFS(const Node& startNode) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Track the nodes we have discovered by their Color
 | 
					  // Create local object to track the information gathered during traversal
 | 
				
			||||||
  for (const auto &node : nodes_) {
 | 
					  InfoBFS searchInfo;
 | 
				
			||||||
    node.color = White;
 | 
					 | 
				
			||||||
    // Track distance from the startNode
 | 
					 | 
				
			||||||
    node.distance = 0;
 | 
					 | 
				
			||||||
    // Track predecessor using node that discovers this node
 | 
					 | 
				
			||||||
    // + If this is the startNode, predecessor remains nullptr
 | 
					 | 
				
			||||||
    node.predecessor = nullptr;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Create a queue to visit discovered nodes in FIFO order
 | 
					  // Create a queue to visit discovered nodes in FIFO order
 | 
				
			||||||
  std::queue<const Node *> visitQueue;
 | 
					  std::queue<const Node *> visitQueue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Mark the startNode as in progress until we finish checking adjacent nodes
 | 
					  // Mark the startNode as in progress until we finish checking adjacent nodes
 | 
				
			||||||
  startNode.color = Gray;
 | 
					  searchInfo[startNode.number].discovered = Gray;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Visit the startNode
 | 
					  // Visit the startNode
 | 
				
			||||||
  visitQueue.push(&startNode);
 | 
					  visitQueue.push(&startNode);
 | 
				
			||||||
@ -40,20 +33,23 @@ void Graph::BFS(const Node& startNode) const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Check if we have already discovered all the adjacentNodes to thisNode
 | 
					    // Check if we have already discovered all the adjacentNodes to thisNode
 | 
				
			||||||
    for (const auto &adjacent : thisNode->adjacent) {
 | 
					    for (const auto &adjacent : thisNode->adjacent) {
 | 
				
			||||||
      if (GetNode(adjacent).color == White) {
 | 
					      if (searchInfo[adjacent].discovered == White) {
 | 
				
			||||||
        std::cout << "Found undiscovered adjacentNode: " << adjacent << "\n";
 | 
					        std::cout << "Found undiscovered adjacentNode: " << adjacent << "\n";
 | 
				
			||||||
        // Mark the adjacent node as in progress
 | 
					        // Mark the adjacent node as in progress
 | 
				
			||||||
        GetNode(adjacent).color = Gray;
 | 
					        searchInfo[adjacent].discovered = Gray;
 | 
				
			||||||
        GetNode(adjacent).distance = thisNode->distance + 1;
 | 
					        searchInfo[adjacent].distance = searchInfo[thisNode->number].distance + 1;
 | 
				
			||||||
        GetNode(adjacent).predecessor = &GetNode(thisNode->number);
 | 
					        searchInfo[adjacent].predecessor = &GetNode(thisNode->number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Add the discovered node the the visitQueue
 | 
					        // Add the discovered node the the visitQueue
 | 
				
			||||||
        visitQueue.push(&GetNode(adjacent));
 | 
					        visitQueue.push(&GetNode(adjacent));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // We are finished with this node and the adjacent nodes; Mark it discovered
 | 
					    // We are finished with this node and the adjacent nodes; Mark it discovered
 | 
				
			||||||
    GetNode(thisNode->number).color = Black;
 | 
					    searchInfo[thisNode->number].discovered = Black;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Return the information gathered from this search, JIC caller needs it
 | 
				
			||||||
 | 
					  return searchInfo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::deque<Node> Graph::PathBFS(const Node &start, const Node &finish) const
 | 
					std::deque<Node> Graph::PathBFS(const Node &start, const Node &finish) const
 | 
				
			||||||
@ -62,8 +58,8 @@ std::deque<Node> Graph::PathBFS(const Node &start, const Node &finish) const
 | 
				
			|||||||
  // + If the caller modifies these, it will not impact the graph's data
 | 
					  // + If the caller modifies these, it will not impact the graph's data
 | 
				
			||||||
  std::deque<Node> path;
 | 
					  std::deque<Node> path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  BFS(start);
 | 
					  InfoBFS searchInfo = BFS(start);
 | 
				
			||||||
  const Node * next = finish.predecessor;
 | 
					  const Node * next = searchInfo[finish.number].predecessor;
 | 
				
			||||||
  bool isValid = false;
 | 
					  bool isValid = false;
 | 
				
			||||||
  do {
 | 
					  do {
 | 
				
			||||||
    // If we have reached the start node, we have found a valid path
 | 
					    // If we have reached the start node, we have found a valid path
 | 
				
			||||||
@ -74,7 +70,7 @@ std::deque<Node> Graph::PathBFS(const Node &start, const Node &finish) const
 | 
				
			|||||||
    path.emplace_front(*next);
 | 
					    path.emplace_front(*next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Move to the next node
 | 
					    // Move to the next node
 | 
				
			||||||
    next = next->predecessor;
 | 
					    next = searchInfo[next->number].predecessor;
 | 
				
			||||||
  } while (next != nullptr);
 | 
					  } while (next != nullptr);
 | 
				
			||||||
  // Use emplace_back to call Node copy constructor
 | 
					  // Use emplace_back to call Node copy constructor
 | 
				
			||||||
  path.emplace_back(finish);
 | 
					  path.emplace_back(finish);
 | 
				
			||||||
@ -86,29 +82,30 @@ std::deque<Node> Graph::PathBFS(const Node &start, const Node &finish) const
 | 
				
			|||||||
  return path;
 | 
					  return path;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graph::DFS() const
 | 
					InfoDFS Graph::DFS() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Track the nodes we have discovered
 | 
					  // Track the nodes we have discovered
 | 
				
			||||||
  for (const auto &node : nodes_) node.color = White;
 | 
					  InfoDFS searchInfo;
 | 
				
			||||||
  int time = 0;
 | 
					  int time = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Visit each node in the graph
 | 
					  // Visit each node in the graph
 | 
				
			||||||
  for (const auto& node : nodes_) {
 | 
					  for (const auto& node : nodes_) {
 | 
				
			||||||
    std::cout << "Visiting node " << node.number << std::endl;
 | 
					    std::cout << "Visiting node " << node.number << std::endl;
 | 
				
			||||||
    // If the node is undiscovered, visit it
 | 
					    // If the node is undiscovered, visit it
 | 
				
			||||||
    if (node.color == White) {
 | 
					    if (searchInfo[node.number].discovered == White) {
 | 
				
			||||||
      std::cout << "Found undiscovered node: " << node.number << std::endl;
 | 
					      std::cout << "Found undiscovered node: " << node.number << std::endl;
 | 
				
			||||||
      // Visiting the undiscovered node will check it's adjacent nodes
 | 
					      // Visiting the undiscovered node will check it's adjacent nodes
 | 
				
			||||||
      DFSVisit(time, node);
 | 
					      DFSVisit(time, node, searchInfo);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return searchInfo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graph::DFS(const Node &startNode) const
 | 
					InfoDFS Graph::DFS(const Node &startNode) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Track the nodes we have discovered
 | 
					  // Track the nodes we have discovered
 | 
				
			||||||
  for (const auto &node : nodes_) node.color = White;
 | 
					  InfoDFS searchInfo;
 | 
				
			||||||
  int time = 0;
 | 
					  int time = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto startIter = std::find(nodes_.begin(), nodes_.end(),
 | 
					  auto startIter = std::find(nodes_.begin(), nodes_.end(),
 | 
				
			||||||
@ -119,10 +116,10 @@ void Graph::DFS(const Node &startNode) const
 | 
				
			|||||||
  while (startIter != nodes_.end()) {
 | 
					  while (startIter != nodes_.end()) {
 | 
				
			||||||
    std::cout << "Visiting node " << startIter->number << std::endl;
 | 
					    std::cout << "Visiting node " << startIter->number << std::endl;
 | 
				
			||||||
    // If the startIter is undiscovered, visit it
 | 
					    // If the startIter is undiscovered, visit it
 | 
				
			||||||
    if (startIter->color == White) {
 | 
					    if (searchInfo[startIter->number].discovered == White) {
 | 
				
			||||||
      std::cout << "Found undiscovered node: " << startIter->number << std::endl;
 | 
					      std::cout << "Found undiscovered node: " << startIter->number << std::endl;
 | 
				
			||||||
      // Visiting the undiscovered node will check it's adjacent nodes
 | 
					      // Visiting the undiscovered node will check it's adjacent nodes
 | 
				
			||||||
      DFSVisit(time, *startIter);
 | 
					      DFSVisit(time, *startIter, searchInfo);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    startIter++;
 | 
					    startIter++;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -134,20 +131,22 @@ void Graph::DFS(const Node &startNode) const
 | 
				
			|||||||
  while (*startIter != startNode) {
 | 
					  while (*startIter != startNode) {
 | 
				
			||||||
    std::cout << "Visiting node " << startIter->number << std::endl;
 | 
					    std::cout << "Visiting node " << startIter->number << std::endl;
 | 
				
			||||||
    // If the startIter is undiscovered, visit it
 | 
					    // If the startIter is undiscovered, visit it
 | 
				
			||||||
    if (startIter->color == White) {
 | 
					    if (searchInfo[startIter->number].discovered == White) {
 | 
				
			||||||
      std::cout << "Found undiscovered node: " << startIter->number << std::endl;
 | 
					      std::cout << "Found undiscovered node: " << startIter->number << std::endl;
 | 
				
			||||||
      // Visiting the undiscovered node will check it's adjacent nodes
 | 
					      // Visiting the undiscovered node will check it's adjacent nodes
 | 
				
			||||||
      DFSVisit(time, *startIter);
 | 
					      DFSVisit(time, *startIter, searchInfo);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    startIter++;
 | 
					    startIter++;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return searchInfo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Graph::DFSVisit(int &time, const Node& startNode) const
 | 
					void Graph::DFSVisit(int &time, const Node& startNode, InfoDFS &searchInfo) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  startNode.color = Gray;
 | 
					  searchInfo[startNode.number].discovered = Gray;
 | 
				
			||||||
  time++;
 | 
					  time++;
 | 
				
			||||||
  startNode.discoveryFinish.first = time;
 | 
					  searchInfo[startNode.number].discoveryFinish.first = time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Check the adjacent nodes of the startNode
 | 
					  // Check the adjacent nodes of the startNode
 | 
				
			||||||
  for (const auto &adjacent : startNode.adjacent) {
 | 
					  for (const auto &adjacent : startNode.adjacent) {
 | 
				
			||||||
@ -155,26 +154,33 @@ void Graph::DFSVisit(int &time, const Node& startNode) const
 | 
				
			|||||||
                          Node(adjacent, {}));
 | 
					                          Node(adjacent, {}));
 | 
				
			||||||
    // If the adjacentNode is undiscovered, visit it
 | 
					    // If the adjacentNode is undiscovered, visit it
 | 
				
			||||||
    // + Offset by 1 to account for 0 index of discovered vector
 | 
					    // + Offset by 1 to account for 0 index of discovered vector
 | 
				
			||||||
    if (iter->color == White) {
 | 
					    if (searchInfo[iter->number].discovered == White) {
 | 
				
			||||||
      std::cout << "Found undiscovered adjacentNode: "
 | 
					      std::cout << "Found undiscovered adjacentNode: "
 | 
				
			||||||
                << GetNode(adjacent).number << std::endl;
 | 
					                << GetNode(adjacent).number << std::endl;
 | 
				
			||||||
      // Visiting the undiscovered node will check it's adjacent nodes
 | 
					      // Visiting the undiscovered node will check it's adjacent nodes
 | 
				
			||||||
      DFSVisit(time, *iter);
 | 
					      DFSVisit(time, *iter, searchInfo);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  startNode.color = Black;
 | 
					  searchInfo[startNode.number].discovered = Black;
 | 
				
			||||||
  time++;
 | 
					  time++;
 | 
				
			||||||
  startNode.discoveryFinish.second = time;
 | 
					  searchInfo[startNode.number].discoveryFinish.second = time;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::vector<Node> Graph::TopologicalSort(const Node &startNode) const
 | 
					std::vector<Node> Graph::TopologicalSort(const Node &startNode) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  DFS(GetNode(startNode.number));
 | 
					  InfoDFS topological = DFS(GetNode(startNode.number));
 | 
				
			||||||
  std::vector<Node> topological(nodes_);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::sort(topological.begin(), topological.end(), Node::FinishedSort);
 | 
					  std::vector<Node> order(nodes_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  auto comp = [&topological](const Node &a, const Node &b) {
 | 
				
			||||||
 | 
					    return (topological[a.number].discoveryFinish.second <
 | 
				
			||||||
 | 
					      topological[b.number].discoveryFinish.second);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::sort(order.begin(), order.end(), comp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The topologicalOrder is read right-to-left in the final result
 | 
					  // The topologicalOrder is read right-to-left in the final result
 | 
				
			||||||
  // + Output is handled in main as FILO, similar to a stack
 | 
					  // + Output is handled in main as FILO, similar to a stack
 | 
				
			||||||
  return topological;
 | 
					  return order;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,11 +17,46 @@
 | 
				
			|||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <queue>
 | 
					#include <queue>
 | 
				
			||||||
#include <unordered_set>
 | 
					#include <unordered_set>
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************/
 | 
				
			||||||
 | 
					// Structures for tracking information gathered from various traversals
 | 
				
			||||||
 | 
					struct Node;
 | 
				
			||||||
// Color represents the discovery status of any given node
 | 
					// Color represents the discovery status of any given node
 | 
				
			||||||
// + White is undiscovered, Gray is in progress, Black is fully discovered
 | 
					// + White is undiscovered, Gray is in progress, Black is fully discovered
 | 
				
			||||||
enum Color {White, Gray, Black};
 | 
					enum Color {White, Gray, Black};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Information used in all searches
 | 
				
			||||||
 | 
					struct SearchInfo {
 | 
				
			||||||
 | 
					  // Coloring of the nodes is used in both DFS and BFS
 | 
				
			||||||
 | 
					  Color discovered = White;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Information that is only used in BFS
 | 
				
			||||||
 | 
					struct BFS : SearchInfo {
 | 
				
			||||||
 | 
					  // Used to represent distance from start node
 | 
				
			||||||
 | 
					  int distance = 0;
 | 
				
			||||||
 | 
					  // Used to represent the parent node that discovered this node
 | 
				
			||||||
 | 
					  // + If we use this node as the starting point, this will remain a nullptr
 | 
				
			||||||
 | 
					  const Node *predecessor = nullptr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Information that is only used in DFS
 | 
				
			||||||
 | 
					struct DFS : SearchInfo {
 | 
				
			||||||
 | 
					  // Create a pair to track discovery / finish time
 | 
				
			||||||
 | 
					  // + Discovery time is the iteration the node is first discovered
 | 
				
			||||||
 | 
					  // + Finish time is the iteration the node has been checked completely
 | 
				
			||||||
 | 
					  // ++ A finished node has considered all adjacent nodes
 | 
				
			||||||
 | 
					  std::pair<int, int> discoveryFinish;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Store search information in unordered_maps so we can pass it around easily
 | 
				
			||||||
 | 
					// + Allows each node to store relative information on the traversal
 | 
				
			||||||
 | 
					using InfoBFS = std::unordered_map<int, struct BFS>;
 | 
				
			||||||
 | 
					using InfoDFS = std::unordered_map<int, struct DFS>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
// Node structure for representing a graph
 | 
					// Node structure for representing a graph
 | 
				
			||||||
struct Node {
 | 
					struct Node {
 | 
				
			||||||
@ -38,37 +73,11 @@ public:
 | 
				
			|||||||
  friend void swap(Node &a, Node &b) {
 | 
					  friend void swap(Node &a, Node &b) {
 | 
				
			||||||
    std::swap(a.number, b.number);
 | 
					    std::swap(a.number, b.number);
 | 
				
			||||||
    std::swap(a.adjacent, b.adjacent);
 | 
					    std::swap(a.adjacent, b.adjacent);
 | 
				
			||||||
    std::swap(a.color, b.color);
 | 
					 | 
				
			||||||
    std::swap(a.discoveryFinish, b.discoveryFinish);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Don't allow anyone to change these values when using a const reference
 | 
					 | 
				
			||||||
  int number;
 | 
					  int number;
 | 
				
			||||||
  std::vector<int> adjacent;
 | 
					  std::vector<int> adjacent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Mutable members so we can update these values when using a const reference
 | 
					 | 
				
			||||||
  // + Since they need to be modified during traversals
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Coloring of the nodes are used in both DFS and BFS
 | 
					 | 
				
			||||||
  mutable Color color = White;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Used in BFS to represent distance from start node
 | 
					 | 
				
			||||||
  mutable int distance = 0;
 | 
					 | 
				
			||||||
  // Used in BFS to represent the parent node that discovered this node
 | 
					 | 
				
			||||||
  // + If we use this node as the starting point, this will remain a nullptr
 | 
					 | 
				
			||||||
  mutable const Node *predecessor = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Create a pair to track discovery / finish time when using DFS
 | 
					 | 
				
			||||||
  // + Discovery time is the iteration the node is first discovered
 | 
					 | 
				
			||||||
  // + Finish time is the iteration the node has been checked completely
 | 
					 | 
				
			||||||
  // ++ A finished node has considered all adjacent nodes
 | 
					 | 
				
			||||||
  mutable std::pair<int, int> discoveryFinish;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Define a comparator for std::sort
 | 
					 | 
				
			||||||
  // + This will help to sort nodes by finished time after traversal
 | 
					 | 
				
			||||||
  static bool FinishedSort(const Node &node1, const Node &node2)
 | 
					 | 
				
			||||||
  { return node1.discoveryFinish.second < node2.discoveryFinish.second;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Define operator== for std::find; And comparisons between nodes
 | 
					  // Define operator== for std::find; And comparisons between nodes
 | 
				
			||||||
  bool operator==(const Node &b) const { return this->number == b.number;}
 | 
					  bool operator==(const Node &b) const { return this->number == b.number;}
 | 
				
			||||||
  // Define an operator!= for comparing nodes for inequality
 | 
					  // Define an operator!= for comparing nodes for inequality
 | 
				
			||||||
@ -83,24 +92,21 @@ public:
 | 
				
			|||||||
  // Constructor
 | 
					  // Constructor
 | 
				
			||||||
  explicit Graph(std::vector<Node> nodes) : nodes_(std::move(nodes)) {}
 | 
					  explicit Graph(std::vector<Node> nodes) : nodes_(std::move(nodes)) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Breadth First Search
 | 
					  // Breadth First Search
 | 
				
			||||||
  void BFS(const Node& startNode) const;
 | 
					  InfoBFS BFS(const Node& startNode) const;
 | 
				
			||||||
  std::deque<Node> PathBFS(const Node &start, const Node &finish) const;
 | 
					  std::deque<Node> PathBFS(const Node &start, const Node &finish) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Depth First Search
 | 
					  // Depth First Search
 | 
				
			||||||
  void DFS() const;
 | 
					  InfoDFS DFS() const;
 | 
				
			||||||
  // An alternate DFS that checks each node of the graph beginning at startNode
 | 
					  // An alternate DFS that checks each node of the graph beginning at startNode
 | 
				
			||||||
  void DFS(const Node &startNode) const;
 | 
					  InfoDFS DFS(const Node &startNode) const;
 | 
				
			||||||
  // Visit function is used in both versions of DFS
 | 
					  // Visit function is used in both versions of DFS
 | 
				
			||||||
  void DFSVisit(int &time, const Node& startNode) const;
 | 
					  void DFSVisit(int &time, const Node& startNode, InfoDFS &searchInfo) const;
 | 
				
			||||||
  // Topological sort, using DFS
 | 
					  // Topological sort, using DFS
 | 
				
			||||||
  std::vector<Node> TopologicalSort(const Node &startNode) const;
 | 
					  std::vector<Node> TopologicalSort(const Node &startNode) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Returns a copy of a node with the number i within the graph
 | 
					  // Returns a copy of a node with the number i within the graph
 | 
				
			||||||
  // + This uses the private, non-const accessor GetNode()
 | 
					  // + This uses the private, non-const accessor GetNode() and returns a copy
 | 
				
			||||||
  inline Node GetNodeCopy(int i) { return GetNode(i);}
 | 
					  inline Node GetNodeCopy(int i) { return GetNode(i);}
 | 
				
			||||||
  // Return a constant iterator for reading node values
 | 
					  // Return a constant iterator for reading node values
 | 
				
			||||||
  inline std::vector<Node>::const_iterator NodeBegin() { return nodes_.cbegin();}
 | 
					  inline std::vector<Node>::const_iterator NodeBegin() { return nodes_.cbegin();}
 | 
				
			||||||
@ -109,7 +115,7 @@ private:
 | 
				
			|||||||
  // A non-const accessor for direct access to a node with the number value i
 | 
					  // A non-const accessor for direct access to a node with the number value i
 | 
				
			||||||
  inline Node & GetNode(int i)
 | 
					  inline Node & GetNode(int i)
 | 
				
			||||||
  { return *std::find(nodes_.begin(), nodes_.end(), Node(i, {}));}
 | 
					  { return *std::find(nodes_.begin(), nodes_.end(), Node(i, {}));}
 | 
				
			||||||
  // For use with const member functions to access mutable values
 | 
					  // For grabbing a const qualified node
 | 
				
			||||||
  inline const Node & GetNode(int i) const
 | 
					  inline const Node & GetNode(int i) const
 | 
				
			||||||
  { return *std::find(nodes_.begin(), nodes_.end(), Node(i, {}));}
 | 
					  { return *std::find(nodes_.begin(), nodes_.end(), Node(i, {}));}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user