我已将DFS
编码为我的想法,并没有提及任何教科书或伪代码的想法。我想我有一些代码行正在进行不必要的计算。有关降低算法复杂度的任何想法吗?
vector<int>visited;
bool isFound(vector<int>vec,int value)
{
if(std::find(vec.begin(),vec.end(),value)==vec.end())
return false;
else
return true;
}
void dfs(int **graph,int numOfNodes,int node)
{
if(isFound(visited,node)==false)
visited.push_back(node);
vector<int>neighbours;
for(int i=0;i<numOfNodes;i++)
if(graph[node][i]==1)
neighbours.push_back(i);
for(int i=0;i<neighbours.size();i++)
if(isFound(visited,neighbours[i])==false)
dfs(graph,numOfNodes,neighbours[i]);
}
void depthFirstSearch(int **graph,int numOfNodes)
{
for(int i=0;i<numOfNodes;i++)
dfs(graph,numOfNodes,i);
}
PS:有人可以给我发一个链接教我如何插入高质量的C ++代码。我已经尝试过语法高亮,但它没有用完。
答案 0 :(得分:9)
您的DFS具有O(n ^ 2)时间复杂度,这非常糟糕(它应该在O(n + m)中运行)。
这一行破坏了你的实现,因为在向量中搜索需要的时间与其长度成正比:
if(std::find(vec.begin(),vec.end(),value)==vec.end())
为避免这种情况,您可以记住在布尔值数组中访问过的内容。
DFS的第二个问题是,对于较大的图形,它可能会导致堆栈溢出,因为最坏情况下的递归深度等于图中顶点的数量。对此问题的补救措施也很简单:使用std::list<int>
作为您自己的堆栈。
因此,执行DFS的代码应该或多或少看起来像这样:
// n is number of vertices in graph
bool visited[n]; // in this array we save visited vertices
std::list<int> stack;
std::list<int> order;
for(int i = 0; i < n; i++){
if(!visited[i]){
stack.push_back(i);
while(!stack.empty()){
int top = stack.back();
stack.pop_back();
if(visited[top])
continue;
visited[top] = true;
order.push_back(top);
for(all neighbours of top)
if(!visited[neighbour])
stack.push_back(neighbour);
}
}
}