质疑图表的教学方式

时间:2010-12-22 12:42:18

标签: data-structures graph directed-graph

我来自阿根廷,但我认为每个参加过数据结构课程的人都知道图表是什么。如果你这样做,你可能知道什么样的实现是“常见的”或“标准的”。它可以通过List或数组实现。甚至维基百科都这么说。以及Mark Allen Weiss,Bruno Preiss和Luis Joyanes Aguilar。

事情是这样的。没有人认为这不是一个好方法吗?最推荐的方法是通过List。但是考虑到顶点之间只有一条边,我不认为List是这样做的好界面。我的意思是,如果Vertex V1与Vertex V2连接,则只有一个且只有一个边缘。

你认为它不是一个Set而不是一个列表吗?

Class Vertex{
    private Set edges;
    private Object data;

    /** Methods**/
}

只想知道一些意见,你怎么看?

谢谢!

修改 另外,如果我们认为Graph不能有重复的元素,那么HashSet是一个很好的选择,可以最小化插入中顶点的查找。

3 个答案:

答案 0 :(得分:5)

你是正确的指出顶点的邻接最准确地由一组(或多图,多集)的情况建模。那么为什么数据结构书籍会改写关于数组和链表呢?我可以想到三个原因:

  1. 编程语言应该将集合作为原始数据类型的想法是最新的。较老的作家不会考虑使用它,现代作家倾向于遵循该领域的传统。

  2. 数据结构课程的目的之一是使您能够在低(具体)级别以及高(抽象)级别考虑数据的表示。 set是一种抽象数据类型(与链接列表和数组不同)没有明显的低级实现:一些集合最好表示为链表,一些表示为哈希表,一些表示为数组,依此类推。因此,数据结构课程很自然地跳过集合的高级表示到它们的低级实现,为了分析使用它们的算法的行为,你必须知道它们。

  3. 重要的是不要教会如何表示数据类型,因为算法可以使用特定的表示最有效地表达。示例1.要计算图形中每对顶点之间的长度 n 的路径,请通过其邻接矩阵表示图形,并将矩阵提升到幂 n 。如果你坚持将顶点的邻近表示为一组边,那么你将错过这个算法(可以使用标准技术进行并行化)。示例2.针对确切封面问题的Knuth“Dancing Links”算法表示使用双向链接列表的列集,以便可以重用已删除项目中的链接以进行有效的回溯。

答案 1 :(得分:2)

在相对更高的 C / C ++程序员级别,图形/网络的实现方式在很大程度上取决于对其执行的操作。作为一个自己的OR人,我可能在这里对我的回答/例子有偏见。可以在图/网络上实现的一些最有效的算法是多项式时间算法。大多数(如果不是全部)我能想到的多项式时间算法(Dijkstra的最短路径问题,运输问题,最大流量问题等)是最小成本流(MCF)问题的特例。在计算上,解决MCF问题的最有效方法之一是通过网络单纯形算法(其本身是用于求解一般线性程序的单纯形算法的专门化)。

在network-simplex算法中,需要有效地表示生成树(在节点集上)。为了在图中表示生成树,可以使用各种数据结构。这些包括以下节点长度

predecessor[], thread[] and depth[] arrays.

在我遇到的网络单纯形算法的最有效实现中,这些并不表示为数组,而是通过

动态创建的某种内存块。
calloc(number_of_nodes, sizeof(struct vertex));

我不确定(在相对较低的级别)编译器内部实现此内存分配的内容/方式 - 无论是列表/集合/映射。

因此,总而言之,实现图形的最佳方式在很大程度上取决于要对其执行的操作。

网络单纯形算法和有效实现该算法所需的数据结构可以在this book中找到。

答案 2 :(得分:1)

最抽象的是,Set有一个谓词来测试一个元素是否在集合中。它也可以支持提供联合和交集的运营商。差异不是必要的可计算的。

最抽象的是,List支持迭代,子列表和追加。

图表上的大多数算法都要求您迭代边缘,因此首选支持迭代的结构。大多数算法不会尝试两次添加相同的边,因此不需要删除重复项。

当然,库中的大多数集都是有限的,扩展集也支持迭代,所以你可以使用它们,尽管你仍然需要检查重复的成本。

一些基于图的系统确实使用集合作为底层机制,但它们处理无限图而不是有限图,其中内涵集变得有用。