c++ - 根据用户输入使用 C++ 创建图形

标签 c++ graph depth-first-search adjacency-list

我正在尝试从 geeks4geeks 站点修改 C++ 中的 DFS 算法,以便根据用户输入创建图形。

原代码:

// C++ program to print DFS traversal from 
// a given vertex in a  given graph 
#include<iostream> 
#include<list> 
using namespace std; 

// Graph class represents a directed graph 
// using adjacency list representation 
class Graph 
{ 
    int V;    // No. of vertices 

    // Pointer to an array containing 
    // adjacency lists 
    list<int> *adj; 

    // A recursive function used by DFS 
    void DFSUtil(int v, bool visited[]); 
public: 
    Graph(int V);   // Constructor 

    // function to add an edge to graph 
    void addEdge(int v, int w); 

    // DFS traversal of the vertices 
    // reachable from v 
    void DFS(int v); 
}; 

Graph::Graph(int V) 
{ 
    this->V = V; 
    adj = new list<int>[V]; 
} 

void Graph::addEdge(int v, int w) 
{ 
    adj[v].push_back(w); // Add w to v’s list. 
} 

void Graph::DFSUtil(int v, bool visited[]) 
{ 
    // Mark the current node as visited and 
    // print it 
    visited[v] = true; 
    cout << v << " "; 

    // Recur for all the vertices adjacent 
    // to this vertex 
    list<int>::iterator i; 
    for (i = adj[v].begin(); i != adj[v].end(); ++i) 
        if (!visited[*i]) 
            DFSUtil(*i, visited); 
} 

// DFS traversal of the vertices reachable from v. 
// It uses recursive DFSUtil() 
void Graph::DFS(int v) 
{ 
    // Mark all the vertices as not visited 
    bool *visited = new bool[V]; 
    for (int i = 0; i < V; i++) 
        visited[i] = false; 

    // Call the recursive helper function 
    // to print DFS traversal 
    DFSUtil(v, visited); 
} 

int main() 
{ 
    // Create a graph given in the above diagram 
    Graph g(4); 
    g.addEdge(0, 1); 
    g.addEdge(0, 2); 
    g.addEdge(1, 2); 
    g.addEdge(2, 0); 
    g.addEdge(2, 3); 
    g.addEdge(3, 3); 

    cout << "Following is Depth First Traversal"
            " (starting from vertex 2) \n"; 
    g.DFS(2); 

    return 0; 
}

我已将 main() 函数更改为从 cin 中读取,如下所示,代码的其余部分保持不变:

int main() 
{ 
   int V,A[4][2];
    cin>>V;
    Graph g(V); 
    for(int i=0;i<V;i++){
       cin>> A[i][0];
       cin>>A[i][1];
    }
    for (int j=0;j<V;j++){
        g.addEdge(A[j][0], A[j][1]);
    }
    g.DFS(2);
    return 0; 
}

图形在邻接表中给出,例如具有以下输入数据(第一行是 V 参数,其余行表示从一个节点到另一个节点的边):

4 
1 2 
2 3 
3 1 
4 2 
4 1

这些按顺序存储在数组中,所以一旦读取数据,我预计:

A[0][0]=1, A[0][1]=2  (edge 1->2)
A[1][0]=2, A[1][1]=3  (edge 2->3)
...

但是IDE的输出是:

Command terminated by signal 11.

我认为这是一个段错误,这意味着我正在尝试访问我不应该访问的内存,但我不知道如何解决这个问题。有什么想法吗?

最佳答案

您的读取功能的问题是您只能读取每个节点的一条边。所以边缘的一部分被忽略了。考虑这个重构:

int main() 
{ 
    int V,A[2];
    cin>>V;
    Graph g(V); 
    while ( cin>> A[0]>>A[1] ) {
       if (A[0]<0 || A[1]<0 || A[0]>=V || A[1]>=V)
           cout << A[0]<<"->"<<A[1]<<" refers to a non-existent node"<<endl;
       else g.addEdge(A[0], A[1]);
    }
    g.DFS(2);
    return 0; 
}

如您所见,我在读取的数据上添加了验证以避免明显的错误。在你的测试数据上运行它会告诉你你的节点标识有问题:你在测试数据中从 1 到 4,而你的代码期望从 0 到 3(因为该图是作为 V 邻接列表的数组实现的并且您不得超出范围)。

这里是online demo .

关于c++ - 根据用户输入使用 C++ 创建图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54963233/

相关文章:

android - 使用 NDK 在 Android 上进行本地化/本地化

javascript - 动态添加JS代码

计算有向图平方的算法(以邻接表的形式表示)

java - RDF/XML 中的动态数组

algorithm - O(E+V) 算法计算给定图上 2 个节点之间的最短路径数

c++ - 在 emplace_back() 中初始化内部结构

c++ - wcout 是如何工作的?

Python:N Puzzle (8-Puzzle) Solver Heruistics:如何迭代?

Java:随机化方法递归调用的顺序

c++ - 当有许多项目相互依赖时,Visual C++ 中的文件夹结构