繁体   English   中英

C ++有向图深度优先搜索

[英]c++ directed graph depth first search

我正在尝试为有向图编写方法DFS方法。 现在,我遇到了细分错误,我真的不确定它在哪里。 从我对有向图的理解中,我相信我的逻辑是正确的……但是换个新的眼睛会很有帮助。

这是我的功能:

void wdigraph::depth_first (int v) const {

static int fVertex = -1;
static bool* visited = NULL;

if( fVertex == -1 ) {
   fVertex = v;
   visited = new bool[size];
   for( int x = 0; x < size; x++ ) {
      visited[x] = false;
   }
}

cout << label[v];
visited[v] = true;

for (int v = 0; v < adj_matrix.size(); v++) {
   for( int x = 0; x < adj_matrix.size(); x++) {
     if( adj_matrix[v][x] != 0 && visited[x] != false ) {
        cout << " -> ";
        depth_first(x);
     }
     if ( v == fVertex ) {
        fVertex = -1;
        delete [] visited;
        visited = NULL;
     }
   }
}
}

类定义:

class wdigraph {
public:
wdigraph(int =NO_NODES);          // default constructor
~wdigraph() {};                   // destructor
int get_size() { return size; }   // returns size of digraph

void depth_first(int) const;// traverses graph using depth-first search
void print_graph() const;   // prints adjacency matrix of digraph

private:
int size;                         // size of digraph
vector<char> label;               // node labels
vector< vector<int> > adj_matrix; // adjacency matrix
};

谢谢!

您将在程序结束之前删除已visited的对象。 回到起始顶点并不意味着您已经完成。 例如,对于V = {1,2,3}的图,E = {(1,2),(2,1),(1,3)}。

另外,请注意,您将v用作输入参数,也用作for循环变量。

我看到几个问题:

下一行

 if( adj_matrix[v][x] != 0 && visited[x] != false ) {

应该更改为

 if( adj_matrix[v][x] != 0 && visited[x] == false ) {

(您想递归仅在没有被访问过的顶点。)

另外,您正在for循环中创建一个新变量v来隐藏参数v :这是合法的C ++,但这几乎总是一个糟糕的主意。

您可能需要考虑几件事。 首先是函数级静态变量通常不是一个好主意,您可以重新设计并使其成为常规变量(以额外的分配为代价)或实例成员并使它们保持活动状态。

该函数假定邻接矩阵为正方形,但未显示初始化代码,因此应进行检查。 可以通过使内循环条件adj_matrix[v].size() (给定节点v )来消除该假设,否则,如果该变量是不变的,则在该内循环之前添加一个断言: assert( adj_matrix[v].size() == adj_matrix.size() && "adj_matrix is not square!" ); -成员size和自身的adj_matrix大小也一样。

整个算法似乎比应有的复杂,从节点v开始的DFS具有以下一般形式:

dfs( v )
   set visited[ v ]
   operate on node (print node label...)
   for each node reachable from v:
      if not visited[ node ]:
         dfs( node )

您的算法似乎是(以错误的方式)以相反的方向横穿了图形。 您将给定节点设置为visited ,然后尝试找到作为该边缘的起点的任何节点。 也就是说,您不是在尝试从v 到达节点,而是在尝试获取v可以到达的节点。 如果是这种情况(即,如果目标正在打印在v中收敛的所有路径),则必须注意不要两次击中同一条边,否则将陷入无限循环-> stackoverflow。

要看到您将以stackoverlow结尾,请考虑以下示例。 起始节点为1 创建visited矢量并将位置1标记为“访问”。 您发现树中有一个边(0,1),并触发了if: adj_matrix[0][1] != 0 && visited[1] ,因此您以递归方式输入起始节点为1 这次,您无需构造辅助数据,但要注意已visited[1] ,进入循环,找到相同的边并递归调用...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM