It is enough to first perform a deep search and copy each node when he visited. As you say, you need some way to map the nodes in the source graph to the corresponding copies so that the copies of the loops and transverse edges can be connected correctly.
This map is also enough to remember the nodes already visited in DFS.
So in Java you will have something like:
class Node { // Contents of node... Data data; // ... member declarations like array of adjacent nodes final ArrayList<Node> children = new ArrayList<>(); // Recursive graph walker for copying, not called by others. private Node deepCloneImpl(Map<Node, Node> copies) { Node copy = copies.get(this); if (copy == null) { copy = new Node(data); // Map the new node _before_ copying children. copies.put(this, copy); for (Node child : children) copy.children.add(child.deepCloneImpl(copies)); } return copy; } public Node deepClone() { return deepCloneImpl(new HashMap<Node, Node>()); } }
Note that you do not want to override equals or hashCode for Node . A map containing copies is based on equality of links, as defined in Object .
Another approach is to place an extra field in each node that points to the copy, if any, and otherwise null. It just implements the map in a different way. But this requires two passes on the schedule: one to create a copy, and the other to clear these map fields for subsequent reuse.
Gene
source share