【问题标题】:Rudimentary C++ Graph Implementation基本的 C++ 图实现
【发布时间】:2016-12-04 23:36:40
【问题描述】:

我正在为我正在学习的 C++ 类进行图形实现。到目前为止,这是我想出的:

struct Edge {
    int weight;
    Vertex *endpoints[2]; // always will have 2 endpoints, since i'm making this undirected
};

struct Vertex {
    int data; // or id
    list<Edge*> edges;
};

class Graph {
public:
    // constructor, destructor, methods, etc.
private:
    list<Vertex> vertices;
};

目前有点粗糙,但我想我想知道......我是否缺少一些基本的东西?目前这似乎有点太容易了,通常这意味着我设计错了。

我的想法是,图只是一个顶点列表,它有一个边列表,边将有一个边列表,它有两个顶点端点。

除了我将放入图中的一些函数(例如:最短距离、大小、添加顶点等)之外,我在这些结构/类的基本实现中是否遗漏了一些东西?

【问题讨论】:

  • “现在看起来有点太容易了,通常这意味着我设计错了。”我不同意。特别是当您只是设计一个模板类时,越简单越好。不要忘记 addEdge()、addVertex() 等。当你实现这些时,它可能会让你考虑你的数据是如何表示的。
  • 好的,这很好。特别是在这两种方法上,我不能在不添加边的情况下添加顶点(反之亦然),对吧?
  • 我注意到您似乎必须先创建所有顶点,然后添加边?
  • 视情况而定。通常没有。您可以让addEdge() 检查顶点是否存在,如果不存在,则创建它(当然,这仅在您的顶点在身份下关闭时才有效)。

标签: c++ graph


【解决方案1】:

有时您需要设计类似这样的东西,但最有用的实现和数据表示是什么并不清楚(例如,存储点集合还是边集合,或两者都更好?),你会一直遇到这个。

您可能会发现,例如,您的第一个构造函数并不是您真正想要的。让 Graph 类创建顶点而不是传递它们可能更容易。

与其在课堂上工作并玩猜谜游戏,不如退后一步,先处理客户端代码。例如,您需要创建一个 Graph 对象、添加一些点、以某种方式将这些点与边连接等等。

您从客户端发出的调用的顺序会自然而然地出现,函数本身的参数也是如此。了解了客户端的样子后,就可以开始自己实现功能了,实际实现应该是什么样子就更清楚了

【讨论】:

  • 好吧,我猜你是对的。我想我的主要问题是关于什么是图表?我从来没有做过。我将删除构造函数以避免混淆。此外,我还没有真正想到我可能会使用它的真实世界示例。
【解决方案2】:

关于您的实施的评论:

图是对象的集合,其中一些对象对是相关的。因此,您当前的实现是一种潜在的实现方式;您对对象以及它们之间的关系进行建模。

您当前实现的优势主要是沿边缘的恒定查找时间和通用性。 查找时间:如果要访问节点k 的第n个邻居,可以在恒定时间内完成。 通用性:这代表了几乎任何人能想到的图表,尤其是当您将weightdata 的数据类型替换为对象(或Template)时。

您当前实现的缺点是它可能会比理想情况慢。查看边缘会很便宜,但仍然需要两跳而不是一跳(节点->边缘->节点)。此外,使用边列表将花费您 O(d) 时间来查找特定边,其中 d 是图的度数。 (您对指针的依赖还要求该图适合一台计算机的内存;您会遇到 Facebook 的图或美国道路网络的问题。我怀疑并行计算是否是您目前关心的问题。)


实现图表时的注意事项:

但是,您的问题是问这是否是最佳方式。这是一个困难的问题,因为图表的几个特定品质会发挥作用。

边信息:如果顶点相关的方式无关紧要(即边没有权重或值),那么使用边对象就没有什么意义了;这只会减慢你的速度。相反,每个顶点可以只保留一个指向其邻居的指针列表,或其邻居的 ID 列表。

构造: 正如您在 cmets 中所注意到的,您当前的实现要求您在添加边之前有一个可用的顶点。总的来说是这样。但是您可能希望在添加边时动态创建顶点;这可以使构造看起来更干净,但如果顶点具有非常量的查找时间,则需要更多时间。如果您在构建图之前知道所有顶点,那么先显式创建它们然后再创建边可能会有所帮助。

密度:如果图是稀疏的(即每个顶点的边数大致恒定),那么邻接表又是一个好方法。但是,如果它很密集,则使用adjacency matrix 通常可以获得更高的性能。每个顶点都按顺序保存所有其他顶点的列表,因此访问任何边都是一个常数时间操作。

算法:你打算在图上解决什么问题?几个famous graph algorithms 根据图表的表示方式有不同的运行时间。


附录:

查看此问题以了解更多可能对您有所帮助的 cmets: Graph implementation C++

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多