
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- 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.