- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Convert Directed Graph into a Tree
Strong data structures that depict connections among entities are directed graphs. To facilitate analysis or boost algorithmic effectiveness, it could be beneficial to transform a directed graph into a tree structure in some circumstances. In this post, we'll look at two CPP algorithmic approaches for turning a directed graph into a tree. We will go over the algorithm for each method, offer related code applications, and show off each approach's unique results.
Methods Used
Depth−First Search (DFS)
Topological Sorting
Depth−First Search (DFS)
The first approach traverses the graph using a depth−first search algorithm to create a tree structure. We establish edges between each unexplored node and its neighbouring nodes, starting from a root node, to make sure the resultant tree doesn't include any cycles. The algorithm works in the following way:
Algorithm
Choose a root node.
Create a blank tree.
Beginning at the root node, run a depth−first search.
Form an edge from the present node to every unexplored node you come across and recursively examine it.
Keep going until every node has been seen.
Example
#include <iostream> #include <vector> using namespace std; class Graph { private: vector<vector<int>> adjacencyList; public: Graph(int numVertices) { adjacencyList.resize(numVertices); } void addEdge(int u, int v) { adjacencyList[u].push_back(v); adjacencyList[v].push_back(u); } int getNumVertices() { return adjacencyList.size(); } vector<int> getAdjacentNodes(int node) { return adjacencyList[node]; } }; void convertGraphToTreeDFS(Graph& graph, int rootNode, vector<bool>& visited, vector<vector<int>>& tree) { visited[rootNode] = true; for (int adjacentNode : graph.getAdjacentNodes(rootNode)) { if (!visited[adjacentNode]) { tree[rootNode].push_back(adjacentNode); convertGraphToTreeDFS(graph, adjacentNode, visited, tree); } } } void convertGraphToTree(Graph& graph) { int numVertices = graph.getNumVertices(); vector<bool> visited(numVertices, false); vector<vector<int>> tree(numVertices); int rootNode = 0; // Convert graph to tree using DFS convertGraphToTreeDFS(graph, rootNode, visited, tree); // Print tree structure for (int i = 0; i < numVertices; i++) { cout << "Node " << i << " -> "; for (int child : tree[i]) { cout << child << " "; } cout << endl; } } int main() { // Create an instance of the Graph class int numVertices = 5; Graph graph(numVertices); // Add edges to the graph graph.addEdge(0, 1); graph.addEdge(0, 2); graph.addEdge(1, 3); graph.addEdge(1, 4); // Call the function to convert the graph to a tree convertGraphToTree(graph); return 0; }
Output
Node 0 -> 1 2 Node 1 -> 3 4 Node 2 -> Node 3 -> Node 4 ->
Topological Sorting
The third technique turns a directed graph into a tree by using the idea of topological sorting. By guaranteeing that the tree that is created is cycle−free, topological sorting ensures that it is an adequate depiction of the directed graph.
Algorithm
Order the directed graph in topological order.
Create a blank tree.
Build links between present nodes.
Example
#include <iostream> #include <vector> #include <stack> #include <unordered_map> using namespace std; // Structure to represent a node in the tree struct Node { int value; vector<Node*> children; }; // Function to perform topological sorting using DFS void topologicalSortDFS(int node, vector<vector<int>>& graph, vector<bool>& visited, stack<int>& stk) { visited[node] = true; for (int neighbor : graph[node]) { if (!visited[neighbor]) { topologicalSortDFS(neighbor, graph, visited, stk); } } stk.push(node); } // Function to convert directed graph into a tree Node* convertToTree(vector<vector<int>>& graph) { int numVertices = graph.size(); vector<bool> visited(numVertices, false); stack<int> stk; // Perform topological sorting for (int i = 0; i < numVertices; i++) { if (!visited[i]) { topologicalSortDFS(i, graph, visited, stk); } } // Create the tree unordered_map<int, Node*> nodes; Node* root = nullptr; while (!stk.empty()) { int nodeValue = stk.top(); stk.pop(); if (nodes.find(nodeValue) == nodes.end()) { Node* node = new Node{nodeValue, {}}; nodes[nodeValue] = node; if (graph[nodeValue].empty()) { root = node; } else { for (int neighbor : graph[nodeValue]) { if (nodes.find(neighbor) != nodes.end()) { nodes[neighbor]->children.push_back(node); } } } } } return root; } // Function to print the tree in pre-order traversal void printTree(Node* root) { if (root == nullptr) { return; } cout << root->value << " "; for (Node* child : root->children) { printTree(child); } } int main() { // Example graph representation (adjacency list) vector<vector<int>> graph = { {}, // Node 0 {0}, // Node 1 {0}, // Node 2 {1, 2}, // Node 3 {2}, // Node 4 {4}, // Node 5 {3, 4}, // Node 6 }; // Convert directed graph into a tree Node* treeRoot = convertToTree(graph); // Print the tree in pre-order traversal cout << "Tree nodes: "; printTree(treeRoot); return 0; }
Output
Tree nodes: 0
Conclusion
This article talks about two approaches in C to changing a coordinated chart into a tree structure. The strategies investigated are Depth−First Look (DFS), and Topological Sorting. Each approach is clarified, followed by code cases that illustrate the usage and yield of each strategy. The article aims to provide perusers with a comprehensive understanding of how to convert a coordinated chart into a tree using distinctive calculations.