复制一个有向图。输入是有向图中的一个结点指针,返回复制的图中对应的结点指针。有向图中结点的定义为:
C++struct GraphNode {
int data;
vector<GraphNode*> neighbors;
GraphNode(int data) : data(data) {}
};
跟复制带随即指针的链表其实是一样的。思路就是先复制新节点,然后复制连接关系,最后再把新复制的节点弹出来。
算法一次写出来的,很高兴~ 不过好多笔误。
void createClone(GraphNode* node,set<GraphNode*>& visited);
void cloneNeighbors(GraphNode* node,set<GraphNode*>& visited);
void removeClone(GraphNode* node,set<GraphNode*>& visited);
GraphNode *cloneGraph(GraphNode *node) {
if ( !node )
return node;
set<GraphNode*> visited;
createClone(node,visited);
visited.clear();
cloneNeighbors(node,visited);
visited.clear();
GraphNode* newNode = node->neighbors.back();
removeClone(node,visited);
return newNode;
}
void createClone(GraphNode* node,set<GraphNode*>& visited)
{
set<GraphNode*>::iterator it = visited.find(node);
if ( it!=visited.end())
return ;
visited.insert(it,node);
vector<GraphNode*>& connect=node->neighbors;
for(int i=0;i<connect.size();i++)
createClone(connect[i],visited);
GraphNode* clone=new GraphNode(node->data);
connect.push_back(clone);
}
void cloneNeighbors(GraphNode* node,set<GraphNode*>& visited)
{
set<GraphNode*>::iterator it = visited.find(node);
if ( it!=visited.end())
return ;
visited.insert(it,node);
vector<GraphNode*>& connect=node->neighbors;
vector<GraphNode*>& toAdd=connect.back()->neighbors;
for(int i=0;i<connect.size()-1;i++)
cloneNeighbors(connect[i],visited);
for(int i=0;i<connect.size()-1;i++)
toAdd.push_back(connect[i]->neighbors.back());
}
void removeClone(GraphNode* node,set<GraphNode*>& visited)
{
set<GraphNode*>::iterator it = visited.find(node);
if ( it!=visited.end())
return ;
visited.insert(it,node);
vector<GraphNode*>& connect=node->neighbors;
for(int i=0;i<connect.size()-1;i++)
removeClone(connect[i],visited);
connect.pop_back();
}