0

Given a representation of a binary tree which can have the maximum of n nodes:

typedef struct node
{
  int info,n;
  struct node *left,*right;
}tree_node;

Construct an undirected graph from a binary tree which can have the maximum of n nodes.

Graph is represented as a struct:

typedef struct
{
  int n;
  tree_node *nodes[];
  int adjacency_m[][];
}graph;

We can get a tree from graph by using algorithms like Prim, Kruskal or DFS.

Question: Is there an algorithm that creates a graph from a binary tree? For example, if binary tree is traversed in In-order fashion, then how to create an undirected graph from it?

ufo
  • 93
  • 1
  • 11
  • Not in any way the doesn't start with the resulting graph a priori. – StoryTeller - Unslander Monica Sep 06 '16 at 06:43
  • 3
    As far as I was taught - a tree is a graph. – Adrian Jałoszewski Sep 06 '16 at 06:43
  • @Adrian Jałoszewski, See my updated question. The tree has a left and right pointer, and for a graph we need adjacency matrix or adjacency list. – ufo Sep 06 '16 at 06:57
  • 2
    @ufo A tree IS a graph on the abstract level. Your distinction is in the concrete data structures used, but you did not provide the target graph data structure. You can convert a tree structure into a graph structure by fully traversing the tree in any manner, but the efficiency depends on the actual data structures involved. – dhke Sep 06 '16 at 07:10
  • 2
    @ufo a tree is a directed acyclic graph with the speciality of having a root node and every path from the root to a leaf node being unique. You already have adjacency information, they're called `left` and `right` respectively in your code: those are the possible 2 outgoing edges of your node. – BeyelerStudios Sep 06 '16 at 07:13
  • 1
    Every tree is a graph (but not every graph is a tree). Just make a copy of the tree and you will get a graph. – vz0 Sep 06 '16 at 07:24

2 Answers2

7

I'm a bit surprised that you know about in-order traversal, but cannot solve this on your own. I'll give you a basic outline:

I'm assuming that the info member in your tree_node is the node id.

You have to do the following:

1) Initialize your data structures, i.e., set adjacency_m[i][j] = 0 for all i,j, 0 <= i < n, 0 <= j < n

2) In your in-order traversal, when you visit a node:

tree_to_graph(tree_node *node) {
     // add a pointer to the node
     graph->nodes[node->info] = node;

     if(node->left) {
          // if node has a left child, , add adjecancy matrix entries for edges from node -> left, and left -> node
          graph->adjacency_m[node->info][node->left->info] = 1;
          graph->adjacency_m[node->left->info][node->info] = 1;
          tree_to_graph(node->left);
     }
     if(node->right) {
          // if node has a right child, add adjecancy matrix entries for edges from node -> right, and right-> node
          graph->adjacency_m[node->info][node->right->info] = 1;
          graph->adjacency_m[node->right->info][node->info] = 1;
          tree_to_graph(node->right);
     }

 }

Edit: As you can see by the discussion in the comments, your question wasn't really clear. You should distingiush between the abstract, mathematical concepts of a tree and a graph and data structures used to represent them. As you say correctly, BFS, Kruskal and Prim can be used to compute a spanning tree of a graph. As disussed in the comments, any tree is a graph by definition. A graph is often represented with an adjacency matrix, wheras a binary tree is often represented with a recrusive tree-structure. Note that you may as well represent a binary tree with an adjacency matrix (if necessary, you can encode the "left" and "right" child information with different adjacency values, e.g., 1 and 2), and a graph with such a recursive tree-like structure (although for a general graph, you'll have to allow for more than two outgoing edges). In your question, you are asking about converting the representation of a binary tree from a tree-like recursive structure to an adjacency matrix.

mort
  • 12,988
  • 14
  • 52
  • 97
  • In the second if statement, shouldn't the last line be "tree_to_graph(node->right)"? – ufo Sep 06 '16 at 08:04
2

I'll solve your question in a C way assuming you have implemented a graph structure and a function for adding edges to your graph void add(int a, int b). Furthermore (for brevity) I'm assuming you have a static global variable of your graph which is at least some nodes deep (I'm skipping the corner cases, more fun for you).

void tree_to_graph(tree_node *node) {
    if (node->left != NULL) {
        add(n, node->left->n);
        tree_to_graph(node->left);
    }
    if (node->right != NULL) {
        add(n, node->right->n);
        tree_to_graph(node->right);
    }
}

The corner case is when the graph is not deep enough. You should implement the case. The add function should add an edge from a to b in your graph. You should also add a function which adds information to the node, but my code was supposed to be the necessary working minimum, leaving the fun part for you.

Adrian Jałoszewski
  • 1,695
  • 3
  • 17
  • 33