[各種面試題] 複製有向圖

複製一個有向圖。輸入是有向圖中的一個結點指針,返回複製的圖中對應的結點指針。有向圖中結點的定義爲:

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();
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章