简体   繁体   English

C / C ++:创建简单的图形库

[英]C/C++: Creating simple graph library

I've been thinking about creating a class in C++ on graph theory. 我一直在考虑在C ++中基于图论创建一个类。 The idea is it'll be a class to hold indefinite number of vertices and edges for a simple graph (at most one edge between a pair of vertices). 想法是,将为一个简单的图(最多一对顶点之间的一个边)保存无限数量的顶点和边。 The problem is how'd I store this indefinite number of vertices/edges in the most efficient way. 问题是我将如何以最有效的方式存储无限数量的顶点/边。

I came up with the idea of having dynamic pointer to array of vertices as a member in the class. 我想到了在类中将动态指针指向顶点数组的想法。 However, it'd be inefficient, and I also encounter problem of how to determine the connection of vertices (I wouldn't be able to determine which vertices connect with which), if I use this method. 但是,这样做效率低下,如果使用此方法,我还将遇到如何确定顶点连接的问题(我将无法确定哪些顶点与哪个顶点连接)。 The alternative is to create a class Vertex that suppose to contain information of its connectivity. 另一种方法是创建一个Vertex类,该类假定包含其连通性信息。 However, because of indefinite number of edges, I cannot think of other way around other than to use dynamic variables inside Vertex. 但是,由于边的数量不确定,除了在Vertex中使用动态变量外,我无法想到其他方法。 It'd make my code efficiency worse with this approach. 这种方法会使我的代码效率更差。

So is there a better approach? 那么有更好的方法吗?

If you do not plan to frequently add and remove items from inside the collections, I'd use STL vectors . 如果您不打算在集合内部频繁添加和删除项目,则可以使用STL vectors They're fast for iterating through, but not terrible for inserts and removes in the middle. 它们的迭代速度很快,但中间的插入和删除操作并不可怕。

If you want to add / remove anywhere frequently, I'd use STL lists . 如果您想经常在任何地方添加/删除,我将使用STL列表 They're slower for iterating, but insertion / removal is O(1). 它们的迭代速度较慢,但​​是插入/删除操作为O(1)。

You can then define your vertex and edge as something like: 然后,您可以将顶点和边定义为:

class Edge;

class Vertex
{
    // ...
public:
    std::list<Edge> incomingEdges;
    std::list<Edge> outgoingEdges;
}

class Edge
{
    // ...
public:
    Vertex startpoint;
    Vertex endpoint;
}

You'll pretty quickly find yourself wanting both a Vertex and Edge class -- there are too many algorithms that depend on coloring, or weighting, or marking edges, and it's also simpler to mix directed and undirected edges. 您会很快发现自己同时需要Vertex和Edge类-太多的算法依赖于着色,加权或标记边缘,并且混合有向和无向边缘也更加容易。 The odds are good that you aren't going to really care a lot about storing the appropriate references dynamically, because that can be reduced to a vector of pointers. 您不太会真正关心动态存储适当的引用,因为这样可以减少为指针向量。

Another issue to think about is if you will want to store this thing persistently. 要考虑的另一个问题是您是否要永久存储此内容。

Suggestion: try the Simplest Thing That Can Possibly Work first. 建议:尝试可能首先起作用的最简单的方法。 Assuming an Array class that resizes itself as needed, that will look something like 假设一个Array类根据需要调整自身大小,则看起来像

class Vertex {
  Array<Edge> edges ;
  VertexData vd ; // define this for the task.

  public:
     // ctor etc; quiz: what operations?
}

class Edge {
  Vertex v1, v2;
  EdgeData ed;
  public:
     // ctor etc
}

Construct all the vertices and edges with new , don't worry about performance,and write some code against these classes. new构造所有顶点和边,不用担心性能,并针对这些类编写一些代码。

Then go back, think how you'd have liked to write the code, and re-implement the classes to have that interface. 然后回去,觉得你怎么会就喜欢写代码,并重新实现的类有接口。

I'm a little prejudiced, since I used to teach the book and worked for Marshall Cline and Mike Girou, but I think one of the best C++ books for someone trying to really use it effectively is The C++ FAQBook , by Cline, Girou, and Lomow. 自从我曾经教书并为Marshall Cline和Mike Girou工作以来,我有些偏见,但是我认为对于真正有效使用它的人来说,最好的C ++书之一是Cline,Girou撰写的The C ++ FAQBook,和洛莫。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM