C++ C++;图类指针混淆
我试图构建一个图形类,其中图形由邻接列表表示。图形本身是指针向量,其中每个指针指向节点的链接列表。无论出于何种原因,当我使用print graph函数时,程序都不会输出任何内容。谁能告诉我我做错了什么,也许我对指针的误解在哪里?提前谢谢C++ C++;图类指针混淆,c++,pointers,graph,C++,Pointers,Graph,我试图构建一个图形类,其中图形由邻接列表表示。图形本身是指针向量,其中每个指针指向节点的链接列表。无论出于何种原因,当我使用print graph函数时,程序都不会输出任何内容。谁能告诉我我做错了什么,也许我对指针的误解在哪里?提前谢谢 #include <array> #include <vector> #include <tuple> #include <unordered_map> class Node { public:
#include <array>
#include <vector>
#include <tuple>
#include <unordered_map>
class Node
{
public:
int vertex;
int value;
Node* next;
Node(int ver)
{
vertex = ver;
};
};
class Graph
{
public:
int n_nodes;
std::unordered_map<int,Node*> graph;
Graph(int n)
{
n_nodes = n;
for(int i=0;i<n;i++)
{
graph.insert({i,nullptr});
};
};
void add_edge(int src,int des,int val)
{
Node node_des = Node(des);
node_des.value = val;
node_des.next = graph[src];
graph[src] = &node_des;
Node node_src = Node(src);
node_src.value = val;
node_src.next = graph[des];
graph[des] = &node_src;
};
void print_graph()
{
for(int i =0; i<n_nodes;i++)
{
std::string str = "Head "+std::to_string(i);
Node node = *graph[i];
while (&node != nullptr)
{
str=str+" -> "+std::to_string(node.vertex);
node = *(node.next);
};
std::cout<<str<<std::endl;
};
};
};
int main()
{
Graph g = Graph(6);
g.add_edge(0,1,3);
g.add_edge(2,1,4);
g.add_edge(0,4,1);
g.add_edge(4,5,6);
g.add_edge(5,3,2);
g.add_edge(4,3,3);
g.add_edge(3,2,5);
g.add_edge(4,1,1);
g.add_edge(3,1,2);
g.print_graph();
return 0;
}```
#包括
#包括
#包括
#包括
类节点
{
公众:
int顶点;
int值;
节点*下一步;
节点(内部版本)
{
顶点=垂直;
};
};
类图
{
公众:
int n_节点;
std::无序映射图;
图(int n)
{
n_节点=n;
对于(int i=0;i来说,由于@drescherjm,我做了这些更改。问题是我创建了一个局部变量并引用了它的地址,而不是显式地创建一个指针并将其设置为一个新的节点实例,在这个节点实例中,对象的生存期是动态控制的
#include <bits/stdc++.h>
#include <array>
#include <vector>
#include <tuple>
#include <unordered_map>
class Node
{
public:
int vertex;
int value;
Node* next;
Node(int ver)
{
vertex = ver;
};
};
class Graph
{
public:
int n_nodes;
std::unordered_map<int,Node*> graph;
Graph(int n)
{
n_nodes = n;
for(int i=0;i<n;i++)
{
graph.insert({i,nullptr});
};
};
void add_edge(int src,int des,int val)
{
Node * node_des = new Node(des);
node_des->value = val;
node_des->next = graph[src];
graph[src] = node_des;
Node * node_src = new Node(src);
node_src->value = val;
node_src->next = graph[des];
graph[des] = node_src;
};
void print_graph()
{
for(int i =0; i<n_nodes;i++)
{
std::string str = "Head "+std::to_string(i);
Node * node_ptr = graph[i];
while (node_ptr != nullptr)
{
str=str+" -> "+std::to_string(node_ptr->vertex);
node_ptr = node_ptr->next;
};
std::cout<<str<<std::endl;
};
};
};
int main()
{
Graph g = Graph(6);
g.add_edge(0,1,3);
g.add_edge(2,1,4);
g.add_edge(0,4,1);
g.add_edge(4,5,6);
g.add_edge(5,3,2);
g.add_edge(4,3,3);
g.add_edge(3,2,5);
g.add_edge(4,1,1);
g.add_edge(3,1,2);
g.print_graph();
return 0;
}
#包括
#包括
#包括
#包括
#包括
类节点
{
公众:
int顶点;
int值;
节点*下一步;
节点(内部版本)
{
顶点=垂直;
};
};
类图
{
公众:
int n_节点;
std::无序映射图;
图(int n)
{
n_节点=n;
对于(int i=0;ivalue=val;
node_des->next=图形[src];
图[src]=节点;
Node*Node_src=新节点(src);
节点\u src->value=val;
node_src->next=graph[des];
图[des]=node_src;
};
void print_graph()
{
对于(int i=0;ivertex);
node_ptr=node_ptr->next;
};
std::cout如果可能的话,您可以只使用vector of vector而不是链表,并且根本不使用指针。因为内存缓存向量操作中的一些插入可能比链表更快,所以类似以下结构:
struct Node2 {
int vertex;
int value;
};
struct Edge2 {
int src, des, value;
};
struct Graph2 {
int n_nodes;
std::vector<std::vector<Node2>> graph;
void add_edge(Edge2 edge) {
graph[edge.src].emplace_back(edge.des, edge.value);
graph[edge.des].emplace_back(edge.src, edge.value);
}
void add_edge(std::initializer_list<Edge2> edges)
{
std::for_each(edges.begin(), edges.end(), [this](auto &e) { add_edge(e); });
};
}
struct节点2{
int顶点;
int值;
};
结构边2{
int src,des,value;
};
结构图2{
int n_节点;
向量图;
无效添加_边(边2边){
图形[edge.src].emplace_back(edge.des,edge.value);
图形[edge.des].emplace_back(edge.src,edge.value);
}
void add_edge(std::initializer_list edges)
{
std::for_each(edges.begin()、edges.end()、[this](自动&e){add_edge(e);});
};
}
结束比链表更容易、更快
Node Node=*graph[i];然后当(&Node!=nullptr)
节点是一个局部变量(在堆栈上),它永远不能是nullptr。graph[des]=&node_src;
一旦作用域结束,node_src
就不再存在,并且您有一个悬空指针。您不能将局部变量的地址存储在存在时间比局部变量长的结构中。事实上,(&(
任何)!=nullptr)
始终为真。没有地址可能为空的表达式。我将更仔细地重新计算代码。最有可能用于此赋值的是使用Node*和new
而不是Node和&someLocal变量。使用new
可以创建指向内存的指针,在这里可以控制其持续时间,而不是局部变量t超出了范围。谢谢!链表实现将以更少的内存复杂性结束,对吗?顺便说一句,不,它仍然是O(n)在边的数量上。实际上,这取决于,但大多数情况下也不是。每个节点2的大小都比节点小,并且所有节点都连接在一个向量中,因此内存效率较低的唯一可能点是向量本身的备用容量,因此您可以使用shrink_to_fit()虽然我认为向量的索引/可写性增加了内存需求,但我可能把它们与python列表混淆了。