试图理解一个c ++列表

时间:2013-08-01 20:02:33

标签: c++ list

请原谅我的无聊,但我无法理解以下内容:

class Graph
{
    int V;    // No. of vertices
    list<int> *adj;    // A dynamic array of adjacency lists
    void bridgeUtil(int v, bool visited[], int disc[], int low[], int parent[]);

  public:
    Graph(int V);   // Constructor
    void addEdge(int v, int w);   // function to add an edge to graph
    void bridge();    // prints all bridges
};

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

  void Graph::addEdge(int v, int w)
  {
     adj[v].push_back(w);
     adj[w].push_back(v);  // Note: the graph is undirected
  }

任何人都可以解释这个数据结构的工作原理以及用以下内容初始化它时的结果:

  Graph g1(5);
  g1.addEdge(1, 0);
  g1.addEdge(0, 2);
  g1.addEdge(2, 1);
  g1.addEdge(0, 3);
  g1.addEdge(3, 4);

非常感谢!

6 个答案:

答案 0 :(得分:5)

基础数据结构

std::list是一个 doubly linked list ,其行为类似于std::vector,但向量基本上是一个动态数组管理系统。

图表

创建图形时,指定图形将具有的节点总数。每个节点都有自己的列表。

当您调用函数add_edge时,它会在索引v处抓取节点(列表)。然后,它会将数字w添加到该列表,表示存在从节点v到节点w的链接。除了相反之外,在下一个陈述中再次发生同样的情况。它抓取索引w的列表,并将数字v添加到列表中,表示存在从节点w到节点v的链接。

正是由于这种性质,我们找到了评论// Note: the graph is undirected,因为它绘制了从两个节点到另一个节点的路径。

结果

由于每个节点都有自己的列表。我们可以随机选择一个,并使用类似下面的函数找到所有连接到它的节点。

list<int> Graph::getNodes(int v)
{
   return(adj[v]);
}

您的代码的作用

//Creates 5 lists, each one representing a node with possible id [0 - 4]
Graph g1(5);       
g1.addEdge(1, 0);
g1.addEdge(0, 2);
g1.addEdge(2, 1);
g1.addEdge(0, 3);
g1.addEdge(3, 4);

//Results in 5 lists that look like this
/*
  (NODE) | (NODE) | (NODE) | (NODE) | (NODE)
  adj[0] | adj[1] | adj[2] | adj[3] | adj[4]
---------------------------------------------
    1    |    0   |    0   |    0   |   3
    2    |    2   |    1   |    4   |
    3    |        |        |        |
*/

根据这些列表,我可以得出结论:Node 0,我可以Nodes 1, 2 and 3

答案 1 :(得分:2)

看看Wikipedia's article。简而言之,图形由节点和顶点组成。节点是“位置”或“东西”,而顶点是它们之间的连接。您的代码使用列表列表来表示此代码。列表x包含节点x所连接的所有节点。

您的示例图表如下所示: enter image description here

答案 2 :(得分:1)

图是节点之间的一组节点和边。这里,每个节点都是一个数字。每个节点的边缘在列表中表示(列表中的每个条目是边缘另一端的节点)。节点0的邻接在邻接数组中的列表0中。在两个节点之间添加边缘后,您将......在这两个节点之间有一条边。它可能有助于把它画出来。您的图表将如下所示:

0--1
|\ |
| \|
3--2
|
4

答案 3 :(得分:0)

它可以跟踪图形,可以使用邻接图或链接列表。添加5个边后,图形将包含以下顶点:{0,1,2,3,4},并且边缘来自{1-0,0-2,2-1,0-3,3-4}您在寻找更多细节吗?

我不确定它是如何被实际存储的,但两种可行的方式是邻接映射或链接列表。

邻接地图:

\ 0 1 2 3 4 
0| 0 1 1 1 0 
1| 1 0 1 0 0 
2| 1 1 0 0 0
3| 1 0 0 0 1
4| 0 0 0 1 0 

a 0表示顶点未连接,1表示它们是。

链接列表:

0 > 1, 2, 3
1 > 0, 2
2 > 0, 1
3 > 0, 4
4 > 3

表示0变为1,2和3,而4变为3。

答案 4 :(得分:0)

每个Graph实例中都有固定数量的std :: list。在您的示例中,数组中有5个。这个数字不会改变。

数组中的每个条目都是int的双链表。

在X和Y之间添加边会更改两个std :: lists。 X处的数组索引是X的节点列表,并将T添加到其中。 Y处的数组索引是Y的节点列表,并将X添加到其中。

如果你想要一个演练......问你的老师,因为它显然是功课。 : - )

答案 5 :(得分:-1)

enter code here

// Program to print BFS traversal from a given 
// source vertex. BFS(int s) traverses vertices 
// reachable from s. 
#include<iostream> 
#include <list> 

using namespace std; class Graph 
    { 
        int V; // No. of vertices 
    
        // Pointer to an array containing adjacency 
        // lists 
        list<int> *adj; 
    public: 
        Graph(int V); // Constructor 
    
        // function to add an edge to graph 
        void addEdge(int v, int w); 
    
        // prints BFS traversal from a given source s 
        void BFS(int s); 
    }; 
    
    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::BFS(int s) 
    { 
        // Mark all the vertices as not visited 
        bool *visited = new bool[V]; 
        for(int i = 0; i < V; i++) 
            visited[i] = false; 
    
        // Create a queue for BFS 
        list<int> queue; 
    
        // Mark the current node as visited and enqueue it 
        visited[s] = true; 
        queue.push_back(s); 
    
        // 'i' will be used to get all adjacent 
        // vertices of a vertex 
        list<int>::iterator i; 
    
        while(!queue.empty()) 
        { 
            // Dequeue a vertex from queue and print it 
            s = queue.front(); 
            cout << s << " "; 
            queue.pop_front(); 
    
            // Get all adjacent vertices of the dequeued 
            // vertex s. If a adjacent has not been visited, 
            // then mark it visited and enqueue it 
            for (i = adj[s].begin(); i != adj[s].end(); ++i) 
            { 
                if (!visited[*i]) 
                { 
                    visited[*i] = true; 
                    queue.push_back(*i); 
                } 
            } 
        } 
    } 
    
    // Driver program to test methods of graph class 
    int main() 
    { 
        // Create a graph given in the above diagram 
        Graph g(5); 
        g.addEdge(1, 0); 
        g.addEdge(0, 2); 
        g.addEdge(2, 1); 
        g.addEdge(0, 3); 
        g.addEdge(3, 4);
        
    // g.addEdge(3, 3); 
    
        cout << "Following is Breadth First Traversal "
            << "(starting from vertex 2) \n"; 
        g.BFS(2); 
    
        return 0; 
    }