克隆图 Clone a Graph
给你一个图。图的节点定义如下:
struct GNode{
int data;
vector<GNode*> neighbors;
GNode(int dat, int size): data(dat) {
neighbors = vector<GNode*>(size, NULL);
}
};
给你一个图的起始节点,要求克隆这个图。
算法一:下面的算法采用深度优先遍历的方法,复制整个图。
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
using namespace std;
struct GNode{
int data;
vector<GNode*> neighbors;
GNode(int dat, int size): data(dat) {
neighbors = vector<GNode*>(size, NULL);
}
};
GNode* clone_graph(GNode* node, map<GNode*, GNode*> & created)
{
if(created.find(node)!=created.end())
return created[node];
else{
unsigned int size = node->neighbors.size();
GNode* newNode = new GNode(node->data, size);
created[node] = newNode;
if(size>0)
for(unsigned int i=0; i<size; i++)
newNode->neighbors[i] = clone_graph(node->neighbors[i], created);
return newNode;
}
}
// This function perform a breadth first traversal of the graph given a starting node
void print(GNode* node)
{
map<GNode*, bool> visited;
queue<GNode*> que;
que.push(node);
// [] operator will insert a new element if the required key is not yet existent.
visited[node] = true; // every time we enqueue a node, we mark this node as visited
while(!que.empty())
{
GNode* front_node = que.front();
printf("%d|", front_node->data);
if(front_node->neighbors.size()>0)
for(int i=0; i<front_node->neighbors.size(); i++)
if(!visited[front_node->neighbors[i]]){
que.push(front_node->neighbors[i]);
visited[front_node->neighbors[i]] = true;
}
que.pop();
}
}
int main(){
GNode* n0 = new GNode(0,3);
GNode* n1 = new GNode(1,1);
GNode* n2 = new GNode(2,1);
GNode* n3 = new GNode(3,3);
GNode* n4 = new GNode(4,1);
n0->neighbors[0] = n1;
n0->neighbors[1] = n2;
n0->neighbors[2] = n3;
n1->neighbors[0] = n2;
n2->neighbors[0] = n3;
n3->neighbors[0] = n0;
n3->neighbors[1] = n1;
n3->neighbors[2] = n4;
n4->neighbors[0] = n3;
map<GNode*, GNode*> created;
GNode* newNode = clone_graph(n0, created);
print(n0);
cout<<endl;
print(newNode);
}
上面首先建了一个图:
0 ------------------ > 1
| \_ |
| \_ |
| \_ |
| \_ |
\/ \-> \/
3<--------------------2
| |\
| |
|/ |
4
然后再复制该图。
==============================
算法二:采用广度优先遍历,复制整个图。
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *graph) {
if (!graph) return NULL;
unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> map;
queue<UndirectedGraphNode *> q;
q.push(graph);
UndirectedGraphNode *graphCopy = new UndirectedGraphNode(graph->label);
map[graph] = graphCopy;
while (!q.empty()) {
UndirectedGraphNode *node = q.front();
q.pop();
int n = node->neighbors.size();
for (int i = 0; i < n; i++) {
UndirectedGraphNode *neighbor = node->neighbors[i];
// no copy exists
if (map.find(neighbor) == map.end()) {
UndirectedGraphNode *p = new UndirectedGraphNode(neighbor->label);
map[node]->neighbors.push_back(p);
map[neighbor] = p;
q.push(neighbor);
} else { // a copy already exists
map[node]->neighbors.push_back(map[neighbor]);
}
}
}
return graphCopy;
}
};