複製一個有向圖。輸入是有向圖中的一個結點指針,返回複製的圖中對應的結點指針。有向圖中結點的定義爲:
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();
}