[英]Confusion in creating a directed graph in C++
我试图通过读取文本文件来创建有向图,其中每行有两列,第一列是尾部顶点,第二列是头部顶点。 目前只是为了测试我的代码是否有效我试图填充图表并将其打印出来。
我在每个节点插入后打印我的图形。 图形打印工作正常,直到我插入第三个节点“4”,之后第一个节点从1变为0.我没有任何线索的原因。 我想知道在边缘存储节点指针是否是一个好主意。 我这样做是因为我已经在“nodes”向量中有节点信息,因此不想复制它。
输入测试文件:
1 2
4 5
我的数据结构是:node:保存节点id和布尔变量节点脏边:保存指向尾节点和头节点图的指针:保存所有节点和边的向量
输出:
Pushing :1
print called
Nodes are:
1
Pushing :2
print called
Nodes are:
1
2
Pushing :4
print called
0(0) --> 2(0) // Problem this should have been 1(0) --> 2(0)
Nodes are:
1
2
4
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
class node {
public:
node() {}
node(int _nodeId, bool dirty);
int nodeId;
bool dirty;
void operator=(node rhs);
bool operator==(node rhs);
};
class edge {
public:
edge(node *_startNode, node *_endNode): startNode(_startNode), endNode(_endNode) {}
node *startNode, *endNode;
};
node :: node(int _nodeId, bool _dirty) {
nodeId = _nodeId;
dirty = _dirty;
}
void node :: operator=(node rhs) {
this->dirty = rhs.dirty;
this->nodeId = rhs.nodeId;
}
bool node :: operator==(node rhs) {
if (this->nodeId == rhs.nodeId) {
return true;
}
return false;
}
class graph {
public:
void print();
void addEdge(node startNode, node endNode);
void addNode(node n);
void dfs(node s);
private:
vector<edge> edges;
vector<node> nodes;
};
void graph :: addNode(node n) {
// only add this node if it does not exist in the graph
if (find(nodes.begin(), nodes.end(), n) == nodes.end()) {
//print();
cout << "Pushing :"<<n.nodeId<<endl;
nodes.push_back(n);
}
print();
cout << endl;
}
void graph :: dfs(node s) {
// Search node s and mark it as dirty
}
void graph :: print() {
cout << "print called\n";
vector<edge>::iterator itr = edges.begin();
while (itr != edges.end()) {
cout << itr->startNode->nodeId << "("<< itr->startNode->dirty<<") --> ";
cout << itr->endNode->nodeId << "("<< itr->endNode->dirty<<")"<<endl;
++itr;
}
cout << "Nodes are:\n";
for (int i=0; i< nodes.size(); ++i) {
cout << nodes.at(i).nodeId << endl;
}
}
void graph :: addEdge(node startNode, node endNode) {
vector<node>::iterator itrStartNode;
itrStartNode = find(nodes.begin(), nodes.end(), startNode);
vector<node>::iterator itrEndNode;
itrEndNode = find(nodes.begin(), nodes.end(), endNode);
edge e(&(*itrStartNode), &(*itrEndNode));
edges.push_back(e);
}
int main(int argc, char *argv[]) {
graph g;
// Read the file here
ifstream file;
file.open("test.txt", ios::in);
string line;
while (getline(file, line)) {
int startNodeId, endNodeId;
istringstream is(line);
is >> startNodeId >> endNodeId;
node startNode(startNodeId, false);
node endNode(endNodeId, false);
g.addNode(startNode);
g.addNode(endNode);
g.addEdge(startNode, endNode);
}
file.close();
g.print();
return 0;
}
你正在创建临时变量, 例如
node startNode(startNodeId, false);
node endNode(endNodeId, false);
和
edge e(&(*itrStartNode), &(*itrEndNode));
并将指向临时实例的指针存储到容器中, 例如
edge e(&(*itrStartNode), &(*itrEndNode));
edges.push_back(e);
退出创建这些实例的本地作用域( while
循环或addEdge
方法)后,程序将回收存储这些实例的堆栈内存以供其他用户使用。 但是,您的指针仍然指向有效的内存地址(由程序回收或不回复),因此,仍然可能指向有效的数据。 这可能是正在发生的事情,也就是为什么你看到有效看似但不正确的顶点。
使用new
运算符创建超出循环和函数的本地范围的实例,并相应地清理它们(通过delete
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.