Open In App

Clone an Undirected Graph

Cloning of a LinkedList and a Binary Tree with random pointers has already been discussed. The idea behind cloning a graph is pretty much similar.

Recommended Practice

The idea is to do a BFS traversal of the graph and while visiting a node make a clone node of it (a copy of original node). If a node is encountered which is already visited then it already has a clone node.

How to keep track of the visited/cloned nodes? A HashMap/Map is required in order to maintain all the nodes which have already been created. Key stores: Reference/Address of original Node Value stores: Reference/Address of cloned Node A copy of all the graph nodes has been made,

how to connect clone nodes? While visiting the neighboring vertices of a node u get the corresponding cloned node for u , let’s call that cloneNodeU , now visit all the neighboring nodes for u and for each neighbor find the corresponding clone node(if not found create one) and then push into the neighboring vector of cloneNodeU node.

How to verify if the cloned graph is a correct? Do a BFS traversal before and after the cloning of graph. In BFS traversal display the value of a node along with its address/reference. Compare the order in which nodes are displayed, if the values are same but the address/reference is different for both the traversals then the cloned graph is correct.

Implementation:

C++

 `// A C++ program to Clone an Undirected Graph``#include``using` `namespace` `std;` `struct` `GraphNode``{``    ``int` `val;` `    ``//A neighbour vector which contains addresses to``    ``//all the neighbours of a GraphNode``    ``vector neighbours;``};` `// A function which clones a Graph and``// returns the address to the cloned``// src node``GraphNode *cloneGraph(GraphNode *src)``{``    ``//A Map to keep track of all the``    ``//nodes which have already been created``    ``map m;``    ``queue q;` `    ``// Enqueue src node``    ``q.push(src);``    ``GraphNode *node;` `    ``// Make a clone Node``    ``node = ``new` `GraphNode();``    ``node->val = src->val;` `    ``// Put the clone node into the Map``    ``m[src] = node;``    ``while` `(!q.empty())``    ``{``        ``//Get the front node from the queue``        ``//and then visit all its neighbours``        ``GraphNode *u = q.front();``        ``q.pop();``        ``vector v = u->neighbours;``        ``int` `n = v.size();``        ``for` `(``int` `i = 0; i < n; i++)``        ``{``            ``// Check if this node has already been created``            ``if` `(m[v[i]] == NULL)``            ``{``                ``// If not then create a new Node and``                ``// put into the HashMap``                ``node = ``new` `GraphNode();``                ``node->val = v[i]->val;``                ``m[v[i]] = node;``                ``q.push(v[i]);``            ``}` `            ``// add these neighbours to the cloned graph node``            ``m[u]->neighbours.push_back(m[v[i]]);``        ``}``    ``}` `    ``// Return the address of cloned src Node``    ``return` `m[src];``}` `// Build the desired graph``GraphNode *buildGraph()``{``    ``/*``        ``Note : All the edges are Undirected``        ``Given Graph:``        ``1--2``        ``| |``        ``4--3``    ``*/``    ``GraphNode *node1 = ``new` `GraphNode();``    ``node1->val = 1;``    ``GraphNode *node2 = ``new` `GraphNode();``    ``node2->val = 2;``    ``GraphNode *node3 = ``new` `GraphNode();``    ``node3->val = 3;``    ``GraphNode *node4 = ``new` `GraphNode();``    ``node4->val = 4;``    ``vector v;``    ``v.push_back(node2);``    ``v.push_back(node4);``    ``node1->neighbours = v;``    ``v.clear();``    ``v.push_back(node1);``    ``v.push_back(node3);``    ``node2->neighbours = v;``    ``v.clear();``    ``v.push_back(node2);``    ``v.push_back(node4);``    ``node3->neighbours = v;``    ``v.clear();``    ``v.push_back(node3);``    ``v.push_back(node1);``    ``node4->neighbours = v;``    ``return` `node1;``}` `// A simple bfs traversal of a graph to``// check for proper cloning of the graph``void` `bfs(GraphNode *src)``{``    ``map visit;``    ``queue q;``    ``q.push(src);``    ``visit[src] = ``true``;``    ``while` `(!q.empty())``    ``{``        ``GraphNode *u = q.front();``        ``cout << ``"Value of Node "` `<< u->val << ``"\n"``;``        ``cout << ``"Address of Node "` `< v = u->neighbours;``        ``int` `n = v.size();``        ``for` `(``int` `i = 0; i < n; i++)``        ``{``            ``if` `(!visit[v[i]])``            ``{``                ``visit[v[i]] = ``true``;``                ``q.push(v[i]);``            ``}``        ``}``    ``}``    ``cout << endl;``}` `// Driver program to test above function``int` `main()``{``    ``GraphNode *src = buildGraph();``    ``cout << ``"BFS Traversal before cloning\n"``;``    ``bfs(src);``    ``GraphNode *newsrc = cloneGraph(src);``    ``cout << ``"BFS Traversal after cloning\n"``;``    ``bfs(newsrc);``    ``return` `0;``}`

Java

 `// Java program to Clone an Undirected Graph``import` `java.util.*;` `// GraphNode class represents each``// Node of the Graph``class` `GraphNode``{``    ``int` `val;` `    ``// A neighbour Vector which contains references to``    ``// all the neighbours of a GraphNode``    ``Vector neighbours;``    ``public` `GraphNode(``int` `val)``    ``{``        ``this``.val = val;``        ``neighbours = ``new` `Vector();``    ``}``}` `class` `Graph``{``    ``// A method which clones the graph and``    ``// returns the reference of new cloned source node``    ``public` `GraphNode cloneGraph(GraphNode source)``    ``{``        ``Queue q = ``new` `LinkedList();``        ``q.add(source);` `        ``// An HashMap to keep track of all the``        ``// nodes which have already been created``        ``HashMap hm =``                        ``new` `HashMap();` `        ``//Put the node into the HashMap``        ``hm.put(source,``new` `GraphNode(source.val));` `        ``while` `(!q.isEmpty())``        ``{``            ``// Get the front node from the queue``            ``// and then visit all its neighbours``            ``GraphNode u = q.poll();` `            ``// Get corresponding Cloned Graph Node``            ``GraphNode cloneNodeU = hm.get(u);``            ``if` `(u.neighbours != ``null``)``            ``{``                ``Vector v = u.neighbours;``                ``for` `(GraphNode graphNode : v)``                ``{``                    ``// Get the corresponding cloned node``                    ``// If the node is not cloned then we will``                    ``// simply get a null``                    ``GraphNode cloneNodeG = hm.get(graphNode);` `                    ``// Check if this node has already been created``                    ``if` `(cloneNodeG == ``null``)``                    ``{``                        ``q.add(graphNode);` `                        ``// If not then create a new Node and``                        ``// put into the HashMap``                        ``cloneNodeG = ``new` `GraphNode(graphNode.val);``                        ``hm.put(graphNode,cloneNodeG);``                    ``}` `                    ``// add the 'cloneNodeG' to neighbour``                    ``// vector of the cloneNodeG``                    ``cloneNodeU.neighbours.add(cloneNodeG);``                ``}``            ``}``        ``}` `        ``// Return the reference of cloned source Node``        ``return` `hm.get(source);``    ``}` `    ``// Build the desired graph``    ``public` `GraphNode buildGraph()``    ``{``        ``/*``            ``Note : All the edges are Undirected``            ``Given Graph:``            ``1--2``            ``|  |``            ``4--3``        ``*/``        ``GraphNode node1 = ``new` `GraphNode(``1``);``        ``GraphNode node2 = ``new` `GraphNode(``2``);``        ``GraphNode node3 = ``new` `GraphNode(``3``);``        ``GraphNode node4 = ``new` `GraphNode(``4``);``        ``Vector v = ``new` `Vector();``        ``v.add(node2);``        ``v.add(node4);``        ``node1.neighbours = v;``        ``v = ``new` `Vector();``        ``v.add(node1);``        ``v.add(node3);``        ``node2.neighbours = v;``        ``v = ``new` `Vector();``        ``v.add(node2);``        ``v.add(node4);``        ``node3.neighbours = v;``        ``v = ``new` `Vector();``        ``v.add(node3);``        ``v.add(node1);``        ``node4.neighbours = v;``        ``return` `node1;``    ``}` `    ``// BFS traversal of a graph to``    ``// check if the cloned graph is correct``    ``public` `void` `bfs(GraphNode source)``    ``{``        ``Queue q = ``new` `LinkedList();``        ``q.add(source);``        ``HashMap visit =``                          ``new` `HashMap();``        ``visit.put(source,``true``);``        ``while` `(!q.isEmpty())``        ``{``            ``GraphNode u = q.poll();``            ``System.out.println(``"Value of Node "` `+ u.val);``            ``System.out.println(``"Address of Node "` `+ u);``            ``if` `(u.neighbours != ``null``)``            ``{``                ``Vector v = u.neighbours;``                ``for` `(GraphNode g : v)``                ``{``                    ``if` `(visit.get(g) == ``null``)``                    ``{``                        ``q.add(g);``                        ``visit.put(g,``true``);``                    ``}``                ``}``            ``}``        ``}``        ``System.out.println();``    ``}``}` `// Driver code``class` `Main``{``    ``public` `static` `void` `main(String args[])``    ``{``        ``Graph graph = ``new` `Graph();``        ``GraphNode source = graph.buildGraph();``        ``System.out.println(``"BFS traversal of a graph before cloning"``);``        ``graph.bfs(source);``        ``GraphNode newSource = graph.cloneGraph(source);``        ``System.out.println(``"BFS traversal of a graph after cloning"``);``        ``graph.bfs(newSource);``    ``}``}`

Python3

 `from` `collections ``import` `deque` `class` `GraphNode:``    ``def` `__init__(``self``, val``=``0``, neighbors``=``[]):``        ``self``.val ``=` `val``        ``self``.neighbors ``=` `neighbors` `def` `cloneGraph(src: GraphNode) ``-``> GraphNode:``    ``# A Map to keep track of all the``    ``# nodes which have already been created``    ``m ``=` `{}``    ``q ``=` `deque()` `    ``# Enqueue src node``    ``q.append(src)``    ``node ``=` `None` `    ``# Make a clone Node``    ``node ``=` `GraphNode()``    ``node.val ``=` `src.val` `    ``# Put the clone node into the Map``    ``m[src] ``=` `node``    ``while` `q:``        ``# Get the front node from the queue``        ``# and then visit all its neighbors``        ``u ``=` `q.popleft()``        ``v ``=` `u.neighbors``        ``for` `neighbor ``in` `v:``            ``# Check if this node has already been created``            ``if` `neighbor ``not` `in` `m:``                ``# If not then create a new Node and``                ``# put into the HashMap``                ``node ``=` `GraphNode()``                ``node.val ``=` `neighbor.val``                ``m[neighbor] ``=` `node``                ``q.append(neighbor)` `            ``# Add these neighbors to the cloned graph node``            ``m[u].neighbors.append(m[neighbor])` `    ``# Return the address of cloned src Node``    ``return` `m[src]` `# Build the desired graph``def` `buildGraph() ``-``> GraphNode:``    ``"""``    ``Given Graph:``    ``1--2``    ``| |``    ``4--3``    ``"""``    ``node1 ``=` `GraphNode(``1``)``    ``node2 ``=` `GraphNode(``2``)``    ``node3 ``=` `GraphNode(``3``)``    ``node4 ``=` `GraphNode(``4``)``    ``node1.neighbors ``=` `[node2, node4]``    ``node2.neighbors ``=` `[node1, node3]``    ``node3.neighbors ``=` `[node2, node4]``    ``node4.neighbors ``=` `[node3, node1]``    ``return` `node1` `# A simple bfs traversal of a graph to``# check for proper cloning of the graph``def` `bfs(src: GraphNode):``    ``visit ``=` `{}``    ``q ``=` `deque()``    ``q.append(src)``    ``visit[src] ``=` `True``    ``while` `q:``        ``u ``=` `q.popleft()``        ``print``(f``"Value of Node {u.val}"``)``        ``print``(f``"Address of Node {u}"``)``        ``v ``=` `u.neighbors``        ``for` `neighbor ``in` `v:``            ``if` `neighbor ``not` `in` `visit:``                ``visit[neighbor] ``=` `True``                ``q.append(neighbor)` `if` `__name__ ``=``=` `"__main__"``:``    ``src ``=` `buildGraph()``    ``print``(``"BFS Traversal before cloning"``)``    ``bfs(src)``    ``clone ``=` `cloneGraph(src)``    ``print``(``"\nBFS Traversal after cloning"``)``    ``bfs(clone)` `    ``# This code is contributed by vikramshirsath177`

Javascript

 `// A Javascript program to Clone an Undirected Graph` `// program to implement queue data structure``class Queue {``  ``constructor() {``    ``this``.items = [];``  ``}` `  ``// add element to the queue``  ``push(element) {``    ``return` `this``.items.push(element);``  ``}` `  ``// remove element from the queue``  ``pop() {``    ``if` `(``this``.items.length > 0) {``      ``return` `this``.items.shift();``    ``}``  ``}` `  ``// view the front element``  ``front() {``    ``return` `this``.items[0];``  ``}` `  ``// check if the queue is empty``  ``empty() {``    ``return` `this``.items.length == 0;``  ``}` `  ``// the size of the queue``  ``size() {``    ``return` `this``.items.length;``  ``}` `  ``// empty the queue``  ``clear() {``    ``this``.items = [];``  ``}``}``class GraphNode {``  ``constructor() {``    ``this``.val;``    ``//A neighbour array which contains addresses to``    ``//all the neighbours of a GraphNode``    ``this``.neighbours = ``new` `Array();``  ``}``}``class Graph {``  ``// A function which clones a Graph and``  ``// returns the address to the cloned``  ``// src node``  ``cloneGraph(src) {``    ``//A Map to keep track of all the``    ``//nodes which have already been created``    ``let m = ``new` `Map();``    ``let q = ``new` `Queue();` `    ``// Enqueue src node``    ``q.push(src);``    ``let node;` `    ``// Make a clone Node``    ``node = ``new` `GraphNode();``    ``node.val = src.val;` `    ``// Put the clone node into the Map``    ``m.set(src, node);``    ``while` `(!q.empty()) {``      ``//Get the front node from the queue``      ``//and then visit all its neighbours``      ``let u = q.front();``      ``q.pop();``      ``let v = u.neighbours;``      ``let n = v.length;``      ``for` `(let i = 0; i < n; i++) {``        ``// Check if this node has already been created``        ``if` `(m.get(v[i]) == ``null``) {``          ``// If not then create a new Node and``          ``// put into the Map``          ``node = ``new` `GraphNode();``          ``node.val = v[i].val;``          ``m.set(v[i], node);``          ``q.push(v[i]);``        ``}` `        ``// add these neighbours to the cloned graph node``        ``m.get(u).neighbours.push(m.get(v[i]));``      ``}``    ``}` `    ``// Return the address of cloned src Node``    ``return` `m.get(src);``  ``}` `  ``// Build the desired graph``  ``buildGraph() {``    ``/*``          ``Note : All the edges are Undirected``          ``Given Graph:``          ``1--2``          ``| |``          ``4--3``      ``*/``    ``let node1 = ``new` `GraphNode();``    ``node1.val = 1;``    ``let node2 = ``new` `GraphNode();``    ``node2.val = 2;``    ``let node3 = ``new` `GraphNode();``    ``node3.val = 3;``    ``let node4 = ``new` `GraphNode();``    ``node4.val = 4;``    ``let v = ``new` `Array();``    ``v.push(node2);``    ``v.push(node4);``    ``node1.neighbours = v;``    ``v = [];``    ``v.push(node1);``    ``v.push(node3);``    ``node2.neighbours = v;``    ``v = [];``    ``v.push(node2);``    ``v.push(node4);``    ``node3.neighbours = v;``    ``v = [];``    ``v.push(node3);``    ``v.push(node1);``    ``node4.neighbours = v;``    ``return` `node1;``  ``}` `  ``// A simple bfs traversal of a graph to``  ``// check for proper cloning of the graph``  ``bfs(src) {``    ``let visit = ``new` `Map();``    ``let q = ``new` `Queue();``    ``q.push(src);``    ``visit.set(src, ``true``);``    ``while` `(!q.empty()) {``      ``let u = q.front();``      ``console.log(``"Value of Node "` `+ u.val);``      ``console.log(``"Address of Node "` `+ u);``      ``q.pop();``      ``let v = u.neighbours;``      ``let n = v.length;``      ``for` `(let i = 0; i < n; i++) {``        ``if` `(visit.get(v[i]) === undefined) {``          ``visit.set(v[i], ``true``);``          ``q.push(v[i]);``        ``}``      ``}``    ``}``    ``console.log(``"        "``);``  ``}``}` `// Driver program to test above function``let graph = ``new` `Graph();``let src = graph.buildGraph();``console.log(``"BFS Traversal before cloning"``);``graph.bfs(src);``let newsrc = graph.cloneGraph(src);``console.log(``"BFS Traversal after cloning"``);``graph.bfs(newsrc);` `// This code is contributed by satwiksuman.`

C#

 `// A C# program to Clone an Undirected Graph``using` `System;``using` `System.Collections.Generic;``using` `System.Linq;` `class` `GraphNode``{``public` `int` `val;``public` `List neighbors;``public` `GraphNode(``int` `val = 0, List neighbors = ``null``)``{``    ``this``.val = val;``    ``this``.neighbors = neighbors ?? ``new` `List();``}``}` `class` `Program``{``static` `GraphNode CloneGraph(GraphNode src)``{``// A Dictionary to keep track of all the``// nodes which have already been created``Dictionary m = ``new` `Dictionary();``Queue q = ``new` `Queue();``    ``// Enqueue src node``    ``q.Enqueue(src);``    ``GraphNode node = ``null``;` `    ``// Make a clone Node``    ``node = ``new` `GraphNode();``    ``node.val = src.val;` `    ``// Put the clone node into the Dictionary``    ``m[src] = node;``    ``while` `(q.Count > 0)``    ``{``        ``// Get the front node from the queue``        ``// and then visit all its neighbors``        ``GraphNode u = q.Dequeue();``        ``List v = u.neighbors;``        ``foreach` `(GraphNode neighbor ``in` `v)``        ``{``            ``// Check if this node has already been created``            ``if` `(!m.ContainsKey(neighbor))``            ``{``                ``// If not then create a new Node and``                ``// put into the Dictionary``                ``node = ``new` `GraphNode();``                ``node.val = neighbor.val;``                ``m[neighbor] = node;``                ``q.Enqueue(neighbor);``            ``}` `            ``// Add these neighbors to the cloned graph node``            ``m[u].neighbors.Add(m[neighbor]);``        ``}``    ``}` `    ``// Return the address of cloned src Node``    ``return` `m[src];``}` `// Build the desired graph``static` `GraphNode BuildGraph()``{``    ``/*``    ``Given Graph:``    ``1--2``    ``| |``    ``4--3``    ``*/``    ``GraphNode node1 = ``new` `GraphNode(1);``    ``GraphNode node2 = ``new` `GraphNode(2);``    ``GraphNode node3 = ``new` `GraphNode(3);``    ``GraphNode node4 = ``new` `GraphNode(4);``    ``node1.neighbors = ``new` `List { node2, node4 };``    ``node2.neighbors = ``new` `List { node1, node3 };``    ``node3.neighbors = ``new` `List { node2, node4 };``    ``node4.neighbors = ``new` `List { node3, node1 };``    ``return` `node1;``}` `// A simple bfs traversal of a graph to``// check for proper cloning of the graph``static` `void` `Bfs(GraphNode src)``{``    ``Dictionary visit = ``new` `Dictionary();``    ``Queue q = ``new` `Queue();``    ``q.Enqueue(src);``    ``visit[src] = ``true``;``    ``while` `(q.Count > 0)``    ``{``        ``GraphNode u = q.Dequeue();``Console.WriteLine(``"Value: "` `+ u.val);``List v = u.neighbors;``foreach` `(GraphNode neighbor ``in` `v)``{``if` `(!visit.ContainsKey(neighbor))``{``visit[neighbor] = ``true``;``q.Enqueue(neighbor);``}``}``}``}` `static` `void` `Main(``string``[] args)``{``GraphNode src = BuildGraph();``GraphNode clone = CloneGraph(src);``Console.WriteLine(``"Original Graph: "``);``Bfs(src);``Console.WriteLine(``"Cloned Graph: "``);``Bfs(clone);``}``}`  `//This code is contributed by shivamsharma215`

Output

```BFS Traversal before cloning
Value of Node 1
Value of Node 2
Value of Node 4
Value of Node 3

BFS Traversal after cloning
Value of Node 1