무방향 그래프 복제

무방향 그래프 복제
GfG Practice에서 사용해 보세요. 무방향 그래프 복제

주어진  연결된 무방향 그래프  인접리스트로 표현  조정목록[][]  ~와 함께  노드와   각 노드가 있는 가장자리  고유 라벨  ~에서  0 ~ n-1 각 adj[i]는 꼭짓점 i에 연결된 꼭짓점 목록을 나타냅니다.

만들기  클론  그래프의 각 노드가 정수를 포함하는 그래프   그리고 배열( 이웃 ) 노드의   현재 노드에 인접한 노드를 포함합니다.

클래스 노드 {
값: 정수
이웃: 목록[노드]
}

당신의 임무는 주어진 그래프를 복제하고 복제된 그래프에 대한 참조를 반환하는 것입니다.

메모: 주어진 그래프의 올바른 복사본을 반환하면 출력은 true가 됩니다. 그렇지 않고 복사본이 올바르지 않으면 거짓으로 인쇄됩니다.

입력: n = 4 adjList[][] = [[1 2] [0 2] [0 1 3] [2]]
산출: 진실
설명:
무방향 그래프 복제
복제된 그래프가 원본과 동일하므로 출력은 true입니다.

입력: n = 3 adjList[][] = [[1 2] [0] [0]]
산출: 진실
설명:
복제된 그래프가 원본과 동일하므로 출력은 true입니다.

목차

방문/복제된 노드를 추적해야 하는 이유는 무엇입니까?

그래프를 복제할 때 무한 재귀 및 중복 작업을 방지하려면 방문했거나 복제된 노드를 추적해야 합니다. 그래프에는 이미 복제한 노드를 추적하지 않고 주기(노드가 이전에 방문한 노드를 다시 가리킬 수 있음)가 포함될 수 있으므로 복제 기능은 동일한 노드를 끝없이 다시 방문하여 스택 오버플로 또는 잘못된 복제가 발생합니다.

방문/복제된 노드를 추적하는 방법은 무엇입니까?

이미 생성된 모든 노드를 유지하려면 HashMap/Map이 필요합니다. 키 스토어 : 원래 노드의 참조/주소 가치 매장

클론 노드를 연결하는 방법은 무엇입니까?

인접한 꼭지점을 방문하는 동안 마디 ~에 해당 복제를 얻으십시오 마디 당신은 그렇게 부르자 안에 이제 모든 이웃 노드를 방문하여 ~에 각 이웃에 대해 해당 복제 노드를 찾은 다음(찾지 못한 경우 새로 생성) 다음 벡터의 이웃 벡터로 푸시합니다. 안에 마디. 

복제된 그래프가 올바른지 어떻게 확인하나요?

복제하기 전에 원본 그래프에서 BFS 순회를 수행한 다음 복제가 완료된 후 복제된 그래프에서 다시 BFS 순회를 수행합니다. 각 순회 중에 주소(또는 참조)와 함께 각 노드의 값을 인쇄합니다. 복제의 정확성을 확인하려면 두 순회에서 방문한 노드의 순서를 비교하십시오. 노드 값이 동일한 순서로 표시되지만 해당 주소(또는 참조)가 다른 경우 그래프가 성공적으로 올바르게 복제되었음을 확인합니다.

방법 알아보기 여러 개의 연결된 구성 요소가 있는 그래프를 포함하여 무방향 그래프 복제 BFS 또는 DFS를 사용하여 모든 노드와 에지의 완전한 전체 복사본을 보장합니다.

[접근 방법 1] BFS 순회 사용 - O(V+E) 시간 및 O(V) 공간

BFS 접근 방식에서는 그래프가 큐를 사용하여 반복적으로 복제됩니다. 초기 노드를 복제하여 대기열에 배치하는 것으로 시작합니다. 대기열의 각 노드를 처리하면서 이웃을 방문합니다. 이웃이 아직 복제되지 않은 경우 복제본을 생성하여 맵에 저장하고 나중에 처리하기 위해 대기열에 넣습니다. 그런 다음 이웃의 복제본을 현재 노드의 복제본의 이웃 목록에 추가합니다. 이 프로세스는 모든 노드가 너비 우선 순서로 방문되도록 수준별로 계속됩니다. BFS는 깊은 재귀를 피하고 크거나 넓은 그래프를 효율적으로 처리하는 데 특히 유용합니다.

C++
   #include          #include         #include         #include         using     namespace     std  ;   // Definition for a Node   struct     Node     {      int     val  ;      vector   <  Node  *>     neighbors  ;   };   // Clone the graph    Node  *     cloneGraph  (  Node  *     node  )     {      if     (  !  node  )     return     nullptr  ;      map   <  Node  *       Node  *>     mp  ;      queue   <  Node  *>     q  ;          // Clone the source node      Node  *     clone     =     new     Node  ();      clone  ->  val     =     node  ->  val  ;      mp  [  node  ]     =     clone  ;      q  .  push  (  node  );      while     (  !  q  .  empty  ())     {      Node  *     u     =     q  .  front  ();      q  .  pop  ();      for     (  auto     neighbor     :     u  ->  neighbors  )     {          // Clone neighbor if not already cloned      if     (  mp  .  find  (  neighbor  )     ==     mp  .  end  ())     {      Node  *     neighborClone     =     new     Node  ();      neighborClone  ->  val     =     neighbor  ->  val  ;      mp  [  neighbor  ]     =     neighborClone  ;      q  .  push  (  neighbor  );      }      // Link clone of neighbor to clone of current node      mp  [  u  ]  ->  neighbors  .  push_back  (  mp  [  neighbor  ]);      }      }      return     mp  [  node  ];   }   // Build graph   Node  *     buildGraph  ()     {      Node  *     node1     =     new     Node  ();     node1  ->  val     =     0  ;      Node  *     node2     =     new     Node  ();     node2  ->  val     =     1  ;      Node  *     node3     =     new     Node  ();     node3  ->  val     =     2  ;      Node  *     node4     =     new     Node  ();     node4  ->  val     =     3  ;      node1  ->  neighbors     =     {  node2       node3  };      node2  ->  neighbors     =     {  node1       node3  };      node3  ->  neighbors     =     {  node1       node2       node4  };      node4  ->  neighbors     =     {  node3  };      return     node1  ;   }       // Compare two graphs for structural and value equality   bool     compareGraphs  (  Node  *     node1       Node  *     node2           map   <  Node  *       Node  *>&     visited  )     {      if     (  !  node1     ||     !  node2  )         return     node1     ==     node2  ;          if     (  node1  ->  val     !=     node2  ->  val     ||     node1     ==     node2  )      return     false  ;      visited  [  node1  ]     =     node2  ;      if     (  node1  ->  neighbors  .  size  ()     !=     node2  ->  neighbors  .  size  ())         return     false  ;      for     (  size_t     i     =     0  ;     i      <     node1  ->  neighbors  .  size  ();     ++  i  )     {      Node  *     n1     =     node1  ->  neighbors  [  i  ];      Node  *     n2     =     node2  ->  neighbors  [  i  ];      if     (  visited  .  count  (  n1  ))     {      if     (  visited  [  n1  ]     !=     n2  )         return     false  ;      }     else     {      if     (  !  compareGraphs  (  n1       n2       visited  ))      return     false  ;      }      }      return     true  ;   }   // Driver Code   int     main  ()     {      Node  *     original     =     buildGraph  ();      Node  *     cloned     =     cloneGraph  (  original  );      map   <  Node  *       Node  *>     visited  ;      cout      < <     (  compareGraphs  (  original       cloned       visited  )     ?         'true'     :     'false'  )      < <     endl  ;      return     0  ;   }   
Java
   import     java.util.*  ;   // Definition for a Node   class   Node     {      public     int     val  ;      public     ArrayList   <  Node  >     neighbors  ;      public     Node  ()     {      neighbors     =     new     ArrayList   <>  ();      }      public     Node  (  int     val  )     {      this  .  val     =     val  ;      neighbors     =     new     ArrayList   <>  ();      }   }   public     class   GfG     {      // Clone the graph      public     static     Node     cloneGraph  (  Node     node  )     {      if     (  node     ==     null  )     return     null  ;      Map   <  Node       Node  >     mp     =     new     HashMap   <>  ();      Queue   <  Node  >     q     =     new     LinkedList   <>  ();      // Clone the starting node      Node     clone     =     new     Node  (  node  .  val  );      mp  .  put  (  node       clone  );      q  .  offer  (  node  );      while     (  !  q  .  isEmpty  ())     {      Node     current     =     q  .  poll  ();      for     (  Node     neighbor     :     current  .  neighbors  )     {      // Clone neighbor if it hasn't been cloned yet      if     (  !  mp  .  containsKey  (  neighbor  ))     {      mp  .  put  (  neighbor       new     Node  (  neighbor  .  val  ));      q  .  offer  (  neighbor  );      }      // Add the clone of the neighbor to the current node's clone      mp  .  get  (  current  ).  neighbors  .  add  (  mp  .  get  (  neighbor  ));      }      }      return     mp  .  get  (  node  );      }      // Build graph      public     static     Node     buildGraph  ()     {      Node     node1     =     new     Node  (  0  );      Node     node2     =     new     Node  (  1  );      Node     node3     =     new     Node  (  2  );      Node     node4     =     new     Node  (  3  );      node1  .  neighbors  .  addAll  (  new     ArrayList   <>      (  Arrays  .  asList  (  node2       node3  )));      node2  .  neighbors  .  addAll  (  new     ArrayList   <>      (  Arrays  .  asList  (  node1       node3  )));      node3  .  neighbors  .  addAll  (  new     ArrayList   <>      (  Arrays  .  asList  (  node1       node2       node4  )));      node4  .  neighbors  .  addAll  (  new     ArrayList   <>      (  Arrays  .  asList  (  node3  )));      return     node1  ;      }      // Compare two graphs for structure and value      public     static     boolean     compareGraphs  (  Node     n1       Node     n2           HashMap   <  Node       Node  >     visited  )     {      if     (  n1     ==     null     ||     n2     ==     null  )      return     n1     ==     n2  ;      if     (  n1  .  val     !=     n2  .  val     ||     n1     ==     n2  )      return     false  ;      visited  .  put  (  n1       n2  );      if     (  n1  .  neighbors  .  size  ()     !=     n2  .  neighbors  .  size  ())      return     false  ;      for     (  int     i     =     0  ;     i      <     n1  .  neighbors  .  size  ();     i  ++  )     {      Node     neighbor1     =     n1  .  neighbors  .  get  (  i  );      Node     neighbor2     =     n2  .  neighbors  .  get  (  i  );      if     (  visited  .  containsKey  (  neighbor1  ))     {      if     (  visited  .  get  (  neighbor1  )     !=     neighbor2  )      return     false  ;      }     else     {      if     (  !  compareGraphs  (  neighbor1       neighbor2       visited  ))      return     false  ;      }      }      return     true  ;      }      public     static     void     main  (  String  []     args  )     {      Node     original     =     buildGraph  ();      Node     cloned     =     cloneGraph  (  original  );      boolean     isEqual     =     compareGraphs  (  original       cloned        new     HashMap   <>  ());      System  .  out  .  println  (  isEqual     ?     'true'     :     'false'  );      }   }   
Python
   from   collections   import   deque   # Definition for a Node   class   Node  :   def   __init__  (  self     val  =  0  ):   self  .  val   =   val   self  .  neighbors   =   []   # Clone the graph   def   cloneGraph  (  node  ):   if   not   node  :   return   None   # Map to hold original nodes as keys and their clones as values   mp   =   {}   # Initialize BFS queue   q   =   deque  ([  node  ])   # Clone the starting node   mp  [  node  ]   =   Node  (  node  .  val  )   while   q  :   current   =   q  .  popleft  ()   for   neighbor   in   current  .  neighbors  :   # If neighbor not cloned yet   if   neighbor   not   in   mp  :   mp  [  neighbor  ]   =   Node  (  neighbor  .  val  )   q  .  append  (  neighbor  )   # Link clone of neighbor to the clone of the current node   mp  [  current  ]  .  neighbors  .  append  (  mp  [  neighbor  ])   return   mp  [  node  ]   # Build graph   def   buildGraph  ():   node1   =   Node  (  0  )   node2   =   Node  (  1  )   node3   =   Node  (  2  )   node4   =   Node  (  3  )   node1  .  neighbors   =   [  node2     node3  ]   node2  .  neighbors   =   [  node1     node3  ]   node3  .  neighbors   =   [  node1     node2     node4  ]   node4  .  neighbors   =   [  node3  ]   return   node1   # Compare two graphs structurally and by values   def   compareGraphs  (  n1     n2     visited  ):   if   not   n1   or   not   n2  :   return   n1   ==   n2   if   n1  .  val   !=   n2  .  val   or   n1   is   n2  :   return   False   visited  [  n1  ]   =   n2   if   len  (  n1  .  neighbors  )   !=   len  (  n2  .  neighbors  ):   return   False   for   i   in   range  (  len  (  n1  .  neighbors  )):   neighbor1   =   n1  .  neighbors  [  i  ]   neighbor2   =   n2  .  neighbors  [  i  ]   if   neighbor1   in   visited  :   if   visited  [  neighbor1  ]   !=   neighbor2  :   return   False   else  :   if   not   compareGraphs  (  neighbor1     neighbor2     visited  ):   return   False   return   True   # Driver   if   __name__   ==   '__main__'  :   original   =   buildGraph  ()   cloned   =   cloneGraph  (  original  )   result   =   compareGraphs  (  original     cloned     {})   print  (  'true'   if   result   else   'false'  )   
C#
   using     System  ;   using     System.Collections.Generic  ;   // Definition for a Node   public     class     Node     {      public     int     val  ;      public     List   <  Node  >     neighbors  ;      public     Node  ()     {      neighbors     =     new     List   <  Node  >  ();      }      public     Node  (  int     val  )     {      this  .  val     =     val  ;      neighbors     =     new     List   <  Node  >  ();      }   }   class     GfG     {          // Clone the graph       public     static     Node     CloneGraph  (  Node     node  )     {      if     (  node     ==     null  )         return     null  ;      var     mp     =     new     Dictionary   <  Node       Node  >  ();      var     q     =     new     Queue   <  Node  >  ();      // Clone the starting node      var     clone     =     new     Node  (  node  .  val  );      mp  [  node  ]     =     clone  ;      q  .  Enqueue  (  node  );      while     (  q  .  Count     >     0  )     {      var     current     =     q  .  Dequeue  ();      foreach     (  var     neighbor     in     current  .  neighbors  )     {      // If neighbor not cloned clone it and enqueue      if     (  !  mp  .  ContainsKey  (  neighbor  ))     {      mp  [  neighbor  ]     =     new     Node  (  neighbor  .  val  );      q  .  Enqueue  (  neighbor  );      }      // Add clone of neighbor to clone of current      mp  [  current  ].  neighbors  .  Add  (  mp  [  neighbor  ]);      }      }      return     mp  [  node  ];      }      // Build graph      public     static     Node     BuildGraph  ()     {      var     node1     =     new     Node  (  0  );      var     node2     =     new     Node  (  1  );      var     node3     =     new     Node  (  2  );      var     node4     =     new     Node  (  3  );      node1  .  neighbors  .  AddRange  (  new  []     {     node2       node3     });      node2  .  neighbors  .  AddRange  (  new  []     {     node1       node3     });      node3  .  neighbors  .  AddRange  (  new  []     {     node1       node2       node4     });      node4  .  neighbors  .  AddRange  (  new  []     {     node3     });      return     node1  ;      }      // Compare two graphs for structure and value      public     static     bool     CompareGraphs  (  Node     n1       Node     n2       Dictionary   <  Node       Node  >     visited  )     {      if     (  n1     ==     null     ||     n2     ==     null  )         return     n1     ==     n2  ;          if     (  n1  .  val     !=     n2  .  val     ||     ReferenceEquals  (  n1       n2  ))         return     false  ;      visited  [  n1  ]     =     n2  ;      if     (  n1  .  neighbors  .  Count     !=     n2  .  neighbors  .  Count  )         return     false  ;      for     (  int     i     =     0  ;     i      <     n1  .  neighbors  .  Count  ;     i  ++  )     {      var     neighbor1     =     n1  .  neighbors  [  i  ];      var     neighbor2     =     n2  .  neighbors  [  i  ];      if     (  visited  .  ContainsKey  (  neighbor1  ))     {      if     (  !  ReferenceEquals  (  visited  [  neighbor1  ]     neighbor2  ))         return     false  ;      }     else     {      if     (  !  CompareGraphs  (  neighbor1       neighbor2       visited  ))      return     false  ;      }      }      return     true  ;      }      public     static     void     Main  ()     {      var     original     =     BuildGraph  ();      var     cloned     =     CloneGraph  (  original  );      var     visited     =     new     Dictionary   <  Node       Node  >  ();      Console  .  WriteLine  (  CompareGraphs  (  original       cloned       visited  )         ?     'true'     :     'false'  );      }   }   
JavaScript
   // Definition for a Node   class     Node     {      constructor  (  val     =     0  )     {      this  .  val     =     val  ;      this  .  neighbors     =     [];      }   }   // Clone the graph   function     cloneGraph  (  node  )     {      if     (  !  node  )     return     null  ;      const     mp     =     new     Map  ();      const     q     =     [  node  ];      // Clone the initial node      mp  .  set  (  node       new     Node  (  node  .  val  ));      while     (  q  .  length     >     0  )     {      const     current     =     q  .  shift  ();      for     (  const     neighbor     of     current  .  neighbors  )     {      if     (  !  mp  .  has  (  neighbor  ))     {      mp  .  set  (  neighbor       new     Node  (  neighbor  .  val  ));      q  .  push  (  neighbor  );      }      // Link clone of neighbor to clone of current      mp  .  get  (  current  ).  neighbors  .  push  (  mp  .  get  (  neighbor  ));      }      }      return     mp  .  get  (  node  );   }   // Build graph   function     buildGraph  ()     {      const     node1     =     new     Node  (  0  );      const     node2     =     new     Node  (  1  );      const     node3     =     new     Node  (  2  );      const     node4     =     new     Node  (  3  );      node1  .  neighbors     =     [  node2       node3  ];      node2  .  neighbors     =     [  node1       node3  ];      node3  .  neighbors     =     [  node1       node2       node4  ];      node4  .  neighbors     =     [  node3  ];      return     node1  ;   }   // Compare two graphs structurally and by value   function     compareGraphs  (  n1       n2       visited     =     new     Map  ())     {      if     (  !  n1     ||     !  n2  )         return     n1     ===     n2  ;          if     (  n1  .  val     !==     n2  .  val     ||     n1     ===     n2  )         return     false  ;      visited  .  set  (  n1       n2  );      if     (  n1  .  neighbors  .  length     !==     n2  .  neighbors  .  length  )         return     false  ;      for     (  let     i     =     0  ;     i      <     n1  .  neighbors  .  length  ;     i  ++  )     {      const     neighbor1     =     n1  .  neighbors  [  i  ];      const     neighbor2     =     n2  .  neighbors  [  i  ];      if     (  visited  .  has  (  neighbor1  ))     {      if     (  visited  .  get  (  neighbor1  )     !==     neighbor2  )         return     false  ;          }     else     {      if     (  !  compareGraphs  (  neighbor1       neighbor2       visited  ))      return     false  ;          }      }      return     true  ;   }   // Driver   const     original     =     buildGraph  ();   const     cloned     =     cloneGraph  (  original  );   const     result     =     compareGraphs  (  original       cloned  );   console  .  log  (  result     ?     'true'     :     'false'  );   

산출
true  

[접근법 2] DFS 순회 사용 - O(V+E) 시간 및 O(V) 공간

DFS 접근 방식에서는 그래프가 재귀를 사용하여 복제됩니다. 우리는 주어진 노드에서 시작하여 역추적하기 전에 각 분기를 따라 가능한 한 멀리 탐색합니다. 맵(또는 사전)은 동일한 노드를 여러 번 처리하는 것을 방지하고 주기를 처리하기 위해 이미 복제된 노드를 추적하는 데 사용됩니다. 처음으로 노드를 만나면 해당 노드의 복제본을 생성하고 이를 맵에 저장합니다. 그런 다음 해당 노드의 각 이웃에 대해 이를 재귀적으로 복제하고 복제된 이웃을 현재 노드의 복제본에 추가합니다. 이렇게 하면 반환하기 전에 모든 노드를 깊이 방문하고 그래프 구조가 충실하게 복사됩니다.

C++
   #include          #include         #include         #include         using     namespace     std  ;   // Definition for a Node   struct     Node     {      int     val  ;      vector   <  Node  *>     neighbors  ;   };   // Map to hold original node to its copy   unordered_map   <  Node  *       Node  *>     copies  ;   // Function to clone the graph    Node  *     cloneGraph  (  Node  *     node  )     {          // If the node is NULL return NULL      if     (  !  node  )     return     NULL  ;      // If node is not yet cloned clone it      if     (  copies  .  find  (  node  )     ==     copies  .  end  ())     {      Node  *     clone     =     new     Node  ();      clone  ->  val     =     node  ->  val  ;      copies  [  node  ]     =     clone  ;      // Recursively clone neighbors      for     (  Node  *     neighbor     :     node  ->  neighbors  )     {      clone  ->  neighbors  .  push_back  (  cloneGraph  (  neighbor  ));      }      }      // Return the clone      return     copies  [  node  ];   }   // Build graph   Node  *     buildGraph  ()     {      Node  *     node1     =     new     Node  ();     node1  ->  val     =     0  ;      Node  *     node2     =     new     Node  ();     node2  ->  val     =     1  ;      Node  *     node3     =     new     Node  ();     node3  ->  val     =     2  ;      Node  *     node4     =     new     Node  ();     node4  ->  val     =     3  ;      node1  ->  neighbors     =     {  node2       node3  };      node2  ->  neighbors     =     {  node1       node3  };      node3  ->  neighbors     =     {  node1    node2       node4  };      node4  ->  neighbors     =     {  node3  };      return     node1  ;   }   // Compare two graphs for structural and value equality   bool     compareGraphs  (  Node  *     node1       Node  *     node2       map   <  Node  *       Node  *>&     visited  )     {      if     (  !  node1     ||     !  node2  )         return     node1     ==     node2  ;      if     (  node1  ->  val     !=     node2  ->  val     ||     node1     ==     node2  )      return     false  ;      visited  [  node1  ]     =     node2  ;      if     (  node1  ->  neighbors  .  size  ()     !=     node2  ->  neighbors  .  size  ())         return     false  ;      for     (  size_t     i     =     0  ;     i      <     node1  ->  neighbors  .  size  ();     ++  i  )     {      Node  *     n1     =     node1  ->  neighbors  [  i  ];      Node  *     n2     =     node2  ->  neighbors  [  i  ];      if     (  visited  .  count  (  n1  ))     {      if     (  visited  [  n1  ]     !=     n2  )         return     false  ;      }     else     {      if     (  !  compareGraphs  (  n1       n2       visited  ))      return     false  ;      }      }      return     true  ;   }   // Driver Code   int     main  ()     {      Node  *     original     =     buildGraph  ();      // Clone the graph      Node  *     cloned     =     cloneGraph  (  original  );      // Compare original and cloned graph      map   <  Node  *       Node  *>     visited  ;      cout      < <     (  compareGraphs  (  original       cloned       visited  )     ?         'true'     :     'false'  )      < <     endl  ;      return     0  ;   }   
Java
   import     java.util.*  ;   // Definition for a Node   class   Node     {      int     val  ;      ArrayList   <  Node  >     neighbors  ;      Node  ()     {      neighbors     =     new     ArrayList   <>  ();      }      Node  (  int     val  )     {      this  .  val     =     val  ;      neighbors     =     new     ArrayList   <>  ();      }   }   public     class   GfG     {      // Map to hold original node to its copy      static     HashMap   <  Node       Node  >     copies     =     new     HashMap   <>  ();      // Function to clone the graph using DFS      public     static     Node     cloneGraph  (  Node     node  )     {      // If the node is NULL return NULL      if     (  node     ==     null  )     return     null  ;      // If node is not yet cloned clone it      if     (  !  copies  .  containsKey  (  node  ))     {      Node     clone     =     new     Node  (  node  .  val  );      copies  .  put  (  node       clone  );      // Recursively clone neighbors      for     (  Node     neighbor     :     node  .  neighbors  )     {      clone  .  neighbors  .  add  (  cloneGraph  (  neighbor  ));      }      }      // Return the clone      return     copies  .  get  (  node  );      }      // Build graph      public     static     Node     buildGraph  ()     {      Node     node1     =     new     Node  (  0  );      Node     node2     =     new     Node  (  1  );      Node     node3     =     new     Node  (  2  );      Node     node4     =     new     Node  (  3  );      node1  .  neighbors  .  addAll  (  Arrays  .  asList  (  node2       node3  ));      node2  .  neighbors  .  addAll  (  Arrays  .  asList  (  node1       node3  ));      node3  .  neighbors  .  addAll  (  Arrays  .  asList  (  node1    node2       node4  ));      node4  .  neighbors  .  addAll  (  Arrays  .  asList  (  node3  ));      return     node1  ;      }      // Compare two graphs for structural and value equality      public     static     boolean     compareGraphs  (  Node     node1       Node     node2           HashMap   <  Node       Node  >     visited  )     {      if     (  node1     ==     null     ||     node2     ==     null  )      return     node1     ==     node2  ;      if     (  node1  .  val     !=     node2  .  val     ||     node1     ==     node2  )      return     false  ;      visited  .  put  (  node1       node2  );      if     (  node1  .  neighbors  .  size  ()     !=     node2  .  neighbors  .  size  ())      return     false  ;      for     (  int     i     =     0  ;     i      <     node1  .  neighbors  .  size  ();     i  ++  )     {      Node     n1     =     node1  .  neighbors  .  get  (  i  );      Node     n2     =     node2  .  neighbors  .  get  (  i  );      if     (  visited  .  containsKey  (  n1  ))     {      if     (  visited  .  get  (  n1  )     !=     n2  )      return     false  ;      }     else     {      if     (  !  compareGraphs  (  n1       n2       visited  ))      return     false  ;      }      }      return     true  ;      }      // Driver Code      public     static     void     main  (  String  []     args  )     {      Node     original     =     buildGraph  ();      // Clone the graph      Node     cloned     =     cloneGraph  (  original  );      // Compare original and cloned graph      boolean     result     =     compareGraphs  (  original       cloned       new     HashMap   <>  ());      System  .  out  .  println  (  result     ?     'true'     :     'false'  );      }   }   
Python
   # Definition for a Node   class   Node  :   def   __init__  (  self     val  =  0     neighbors  =  None  ):   self  .  val   =   val   self  .  neighbors   =   neighbors   if   neighbors   is   not   None   else   []   # Map to hold original node to its copy   copies   =   {}   # Function to clone the graph    def   cloneGraph  (  node  ):   # If the node is None return None   if   not   node  :   return   None   # If node is not yet cloned clone it   if   node   not   in   copies  :   # Create a clone of the node   clone   =   Node  (  node  .  val  )   copies  [  node  ]   =   clone   # Recursively clone neighbors   for   neighbor   in   node  .  neighbors  :   clone  .  neighbors  .  append  (  cloneGraph  (  neighbor  ))   # Return the clone   return   copies  [  node  ]   def   buildGraph  ():   node1   =   Node  (  0  )   node2   =   Node  (  1  )   node3   =   Node  (  2  )   node4   =   Node  (  3  )   node1  .  neighbors   =   [  node2     node3  ]   node2  .  neighbors   =   [  node1     node3  ]   node3  .  neighbors   =   [  node1     node2     node4  ]   node4  .  neighbors   =   [  node3  ]   return   node1   # Compare two graphs for structural and value equality   def   compareGraphs  (  node1     node2     visited  ):   if   not   node1   or   not   node2  :   return   node1   ==   node2   if   node1  .  val   !=   node2  .  val   or   node1   is   node2  :   return   False   visited  [  node1  ]   =   node2   if   len  (  node1  .  neighbors  )   !=   len  (  node2  .  neighbors  ):   return   False   for   i   in   range  (  len  (  node1  .  neighbors  )):   n1   =   node1  .  neighbors  [  i  ]   n2   =   node2  .  neighbors  [  i  ]   if   n1   in   visited  :   if   visited  [  n1  ]   !=   n2  :   return   False   else  :   if   not   compareGraphs  (  n1     n2     visited  ):   return   False   return   True   # Driver Code   if   __name__   ==   '__main__'  :   original   =   buildGraph  ()   # Clone the graph using DFS   cloned   =   cloneGraph  (  original  )   # Compare original and cloned graph   visited   =   {}   print  (  'true'   if   compareGraphs  (  original     cloned     visited  )   else   'false'  )   
C#
   using     System  ;   using     System.Collections.Generic  ;   public     class     Node     {      public     int     val  ;      public     List   <  Node  >     neighbors  ;      public     Node  ()     {      val     =     0  ;      neighbors     =     new     List   <  Node  >  ();      }      public     Node  (  int     _val  )     {      val     =     _val  ;      neighbors     =     new     List   <  Node  >  ();      }   }   class     GfG     {      // Dictionary to hold original node to its copy      static     Dictionary   <  Node       Node  >     copies     =     new     Dictionary   <  Node       Node  >  ();      // Function to clone the graph using DFS      public     static     Node     CloneGraph  (  Node     node  )     {      // If the node is NULL return NULL      if     (  node     ==     null  )     return     null  ;      // If node is not yet cloned clone it      if     (  !  copies  .  ContainsKey  (  node  ))     {      Node     clone     =     new     Node  (  node  .  val  );      copies  [  node  ]     =     clone  ;      // Recursively clone neighbors      foreach     (  Node     neighbor     in     node  .  neighbors  )     {      clone  .  neighbors  .  Add  (  CloneGraph  (  neighbor  ));      }      }      // Return the clone      return     copies  [  node  ];      }      // Build graph      public     static     Node     BuildGraph  ()     {      Node     node1     =     new     Node  (  0  );      Node     node2     =     new     Node  (  1  );      Node     node3     =     new     Node  (  2  );      Node     node4     =     new     Node  (  3  );      node1  .  neighbors  .  Add  (  node2  );      node1  .  neighbors  .  Add  (  node3  );      node2  .  neighbors  .  Add  (  node1  );      node2  .  neighbors  .  Add  (  node3  );      node3  .  neighbors  .  Add  (  node1  );      node3  .  neighbors  .  Add  (  node2  );      node3  .  neighbors  .  Add  (  node4  );          node4  .  neighbors  .  Add  (  node3  );      return     node1  ;      }      // Compare two graphs for structural and value equality      public     static     bool     CompareGraphs  (  Node     node1       Node     node2           Dictionary   <  Node       Node  >     visited  )     {      if     (  node1     ==     null     ||     node2     ==     null  )      return     node1     ==     node2  ;      if     (  node1  .  val     !=     node2  .  val     ||     node1     ==     node2  )      return     false  ;      visited  [  node1  ]     =     node2  ;      if     (  node1  .  neighbors  .  Count     !=     node2  .  neighbors  .  Count  )      return     false  ;      for     (  int     i     =     0  ;     i      <     node1  .  neighbors  .  Count  ;     i  ++  )     {      Node     n1     =     node1  .  neighbors  [  i  ];      Node     n2     =     node2  .  neighbors  [  i  ];      if     (  visited  .  ContainsKey  (  n1  ))     {      if     (  visited  [  n1  ]     !=     n2  )      return     false  ;      }     else     {      if     (  !  CompareGraphs  (  n1       n2       visited  ))      return     false  ;      }      }      return     true  ;      }      // Driver Code      public     static     void     Main  ()     {      Node     original     =     BuildGraph  ();      // Clone the graph using DFS      Node     cloned     =     CloneGraph  (  original  );      // Compare original and cloned graph      bool     isEqual     =     CompareGraphs  (  original       cloned       new      Dictionary   <  Node       Node  >  ());      Console  .  WriteLine  (  isEqual     ?     'true'     :     'false'  );      }   }   
JavaScript
   // Definition for a Node   class     Node     {      constructor  (  val     =     0  )     {      this  .  val     =     val  ;      this  .  neighbors     =     [];      }   }   // Map to hold original node to its copy   const     copies     =     new     Map  ();   // Function to clone the graph using DFS   function     cloneGraph  (  node  )     {      // If the node is NULL return NULL      if     (  node     ===     null  )     return     null  ;      // If node is not yet cloned clone it      if     (  !  copies  .  has  (  node  ))     {      const     clone     =     new     Node  (  node  .  val  );      copies  .  set  (  node       clone  );      // Recursively clone neighbors      for     (  let     neighbor     of     node  .  neighbors  )     {      clone  .  neighbors  .  push  (  cloneGraph  (  neighbor  ));      }      }      // Return the clone      return     copies  .  get  (  node  );   }   // Build graph   function     buildGraph  ()     {      const     node1     =     new     Node  (  0  );      const     node2     =     new     Node  (  1  );      const     node3     =     new     Node  (  2  );      const     node4     =     new     Node  (  3  );      node1  .  neighbors  .  push  (  node2       node3  );      node2  .  neighbors  .  push  (  node1       node3  );      node3  .  neighbors  .  push  (  node1       node2       node4  );      node4  .  neighbors  .  push  (  node3  );      return     node1  ;   }   // Compare two graphs for structural and value equality   function     compareGraphs  (  node1       node2       visited     =     new     Map  ())     {      if     (  !  node1     ||     !  node2  )      return     node1     ===     node2  ;      if     (  node1  .  val     !==     node2  .  val     ||     node1     ===     node2  )      return     false  ;      visited  .  set  (  node1       node2  );      if     (  node1  .  neighbors  .  length     !==     node2  .  neighbors  .  length  )      return     false  ;      for     (  let     i     =     0  ;     i      <     node1  .  neighbors  .  length  ;     i  ++  )     {      const     n1     =     node1  .  neighbors  [  i  ];      const     n2     =     node2  .  neighbors  [  i  ];      if     (  visited  .  has  (  n1  ))     {      if     (  visited  .  get  (  n1  )     !==     n2  )      return     false  ;      }     else     {      if     (  !  compareGraphs  (  n1       n2       visited  ))      return     false  ;      }      }      return     true  ;   }   // Driver Code   const     original     =     buildGraph  ();   // Clone the graph using DFS   const     cloned     =     cloneGraph  (  original  );   // Compare original and cloned graph   console  .  log  (  compareGraphs  (  original       cloned  )     ?     'true'     :     'false'  );   

산출
true