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.

Updated on: 2023-07-14T09:29:08+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements