【问题标题】:vector of arrays error in adjacency matrix for graph implementation用于图形实现的邻接矩阵中的数组错误向量
【发布时间】:2019-12-01 07:44:53
【问题描述】:

我正在查看这段代码

using namespace std; 


// A utility function to add an edge in an 
// undirected graph. 
void addEdge(vector<int> adj[], int u, int v) 
{ 
    adj[u].push_back(v); 
    adj[v].push_back(u); 
} 

// A utility function to print the adjacency list 
// representation of graph 
void printGraph(vector<int> adj[], int V) 
{ 
    for (int v = 0; v < V; ++v) 
    { 
        cout << "\n Adjacency list of vertex "
             << v << "\n head "; 
        for (auto x : adj[v]) 
           cout << "-> " << x; 
        printf("\n"); 
    } 
} 

// Driver code 
int main() 
{ 
    int V = 5; 
    vector<int> adj[V]; 
    addEdge(adj, 0, 1); 
    addEdge(adj, 0, 4); 
    addEdge(adj, 1, 2); 
    addEdge(adj, 1, 3); 
    addEdge(adj, 1, 4); 
    addEdge(adj, 2, 3); 
    addEdge(adj, 3, 4); 
    printGraph(adj, V); 
    return 0; 
} 

此代码应打印邻接矩阵中的节点之间的连接,它确实如此。但是,我有一些疑问/问题。

  1. 在添加边函数中,数组的向量是按值传递的。我觉得这是不正确的,应该通过引用传递。除非我在这里错过了一个技巧。

    void addEdge(vector adj[], int u, int v)

  2. 所以我尝试将上述转换为参考函数,如下所示

    void addEdge(vector (&adj)[], int u, int v)

但这当然会因错误而失败:

候选函数不可行:没有已知的来自 'vector 的转换 [V]' 到 'vector (&)[]' 第一个参数 void addEdge(vector (&adj)[], int u, int v)

我知道有不同的方式来表示邻接矩阵,即数组、向量的向量,但如果有人能帮我弄清楚这种语法,我将不胜感激。

谢谢

【问题讨论】:

    标签: c++ arrays function vector declaration


    【解决方案1】:

    您对数组和指针之间的关系感到困惑。第一点,这个

    void addEdge(vector<int> adj[], int u, int v) 
    

    完全完全等价于这个

    void addEdge(vector<int>* adj, int u, int v) 
    

    [] 语法被添加到 C 语言中,专门用来迷惑新手(我想不出任何其他原因)。当您在函数参数中使用[] 时,您实际上是在声明一个指针。

    这是第二点,在 C 或 C++ 中不可能按值传递数组。所以你的担心是多余的。您实际上是在传递一个指向数组第一个元素的指针,这非常有效。

    我的建议是将函数参数中[] 的所有实例更改为*,这样您就不会感到困惑了。

    【讨论】:

      【解决方案2】:

      对于初学者,此代码 sn-p

      int V = 5; 
      vector<int> adj[V]; 
      

      不是 C++ 标准的标准特性。 C++ 不支持变长数组。

      你可以改写

      const int V = 5; 
      vector<int> adj[V]; 
      

      当您通过值传递数组时,指定数组的表达式会隐式转换为指向数组第一个元素的指针。所以实际上数组的每个元素都是使用指针间接传递的。该函数不会创建数组本身的副本。它创建传递的指向数组第一个元素的指针的副本。

      另一方面,声明为数组的函数参数被编译器隐式调整为指向数组元素类型的指针。

      例如这些函数声明

      void f( int a[10] );
      void f( int a[] );
      void f( int *a );
      

      声明同一个函数,并且可以全部包含在程序中,尽管它们是多余的。

      至于这份声明

      void addEdge(vector (&adj)[], int u, int v);
      

      那么你没有指定数组的大小。所以第一个参数的类型不完整。

      【讨论】:

      • 干杯。澄清像 addEdge(adj,0,1) 这样的调用实际上会将指针传递给数组的底层向量?
      • @RickoM 该参数被隐式转换为指向数组第一个元素的指针。所以实际上数组的每个元素都是通过指针间接传递的。使用指针(例如在下标运算符中),您可以更改数组的每个原始元素。
      猜你喜欢
      • 1970-01-01
      • 2017-07-24
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 2014-05-04
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多