我随时都看到有三种表示图形的方法:
然而,我只是简单地理解这些对象和指针表示是什么 - 但是每个招聘人员和许多博客都引用Steve Yegge's博客,他们确实是一个单独的代表。
This widely accepted answer一个非常相似的问题似乎表明顶点结构本身没有指向其他顶点的内部指针,而是所有边都由包含指向相邻顶点的指针的边结构表示。
这种表现如何在任何场景中提供任何可辨别的分析优势?
答案 0 :(得分:1)
从我的头脑中,我希望我的事实是正确的。
从概念上讲,图形试图表示一组节点(或顶点)如何相互关联(连接)(通过边缘)。 但是,在实际的物理设备(存储器)中,我们有一个连续的存储单元阵列。
因此,为了表示图形,我们可以选择使用矩阵。 在这种情况下,我们使用顶点索引作为行和列,如果顶点彼此相邻,则条目的值为1,否则为0。
或者,您也可以通过分配一个对象来表示一个图形来表示一个节点/顶点,该节点/顶点指向与其相邻的所有节点的列表。
当图形密集时,矩阵表示给出了优势,这意味着当大多数节点/顶点彼此连接时。这是因为在这种情况下,通过使用矩阵的输入,它使我们不必为每个连接分配额外的指针(需要字大小的内存)。
对于稀疏图,列表方法更好,因为当顶点之间没有连接时,您不需要考虑0条目。
希望它有所帮助。
答案 1 :(得分:0)
现在我很难找到一个专业的图形算法"。但是,如果你把它想象成你刚刚在白板上绘制的东西的表示,那么它确实可以用对象和指针来表示一个图形,这是非常自然的事情。
考虑一下您希望按特定顺序组合图形节点的场景。 节点具有包含域数据的有效负载,图形结构本身不是程序的核心方面。
当然,你可以为每个操作更新你的列表/矩阵,但是给出了一个"对象和指针"结构,你可以在本地进行合并。此外,如果节点具有有效载荷,则意味着列表/矩阵将以识别实际节点对象的节点id为特征。组合意味着您更新图表表示,遵循节点标识符并执行实际处理。处理实际的节点对象可能会更直观,只需在折叠邻居时删除指针(并删除该节点)。
此外,还有更多方法来表示图表:
答案 2 :(得分:0)
这是我用这个概念创建Graph的方法:
#include <vector>
class Node
{
public:
Node();
void setLink(Node *n); // *n as argument to pass the address of the node
virtual ~Node(void);
private:
vector<Node*> m_links;
};
负责创建顶点之间链接的函数是:
void Node::setLink(Node *n)
{
m_links.push_back(n);
}
答案 3 :(得分:0)
对象和指针表示将空间复杂度降低到精确的V+E
,其中V
是顶点数,E
-边数(从V+2E
在邻接列表中,甚至2V+2E
,如果您将index-> Vertex映射存储在单独的哈希图中),则牺牲了时间复杂度:特定的边缘查找将花费{{1} },等于密集图中的O(E)
(从邻接表中的O(V)向上)。通过删除邻接表中出现的重复边来实现空间节省。