我正在阅读教科书Introduction to Algorithms
又名CLRS
,我想在c中使用mst
算法实现kruskal
,我想知道的是,哪个图表实现我应该使用邻接列表或邻接矩阵吗?我认为在使用邻接列表时对edges
进行排序并不直观,在定义邻接列表时,邻接列表中edge
的表示会令人困惑:
typedef struct tagAdjList
{
int endPointIndex;
struct tagAdjList * next;
}AdjNode, *AdjList, *AdjPNode;
在对边进行排序时,我想使用一个指针数组来指向上面定义的节点,问题是上面定义的结构找不到边start point
而是end point
}。所以我改变了这样的结构:
typedef struct tagAdjList
{
int startPointIndex;
int endPointIndex;
struct tagAdjList * next;
}AdjNode, *AdjList, *AdjPNode;
我想问的是:可以像这样定义邻接列表吗?还是有更好的做法?或者我只是应该使用邻接矩阵(因为我看到有些人在搜索互联网时使用矩阵实现kruskal)?为什么? 抱歉英语不好。任何帮助将不胜感激。
答案 0 :(得分:3)
出于实现Kruskal算法的目的,您以何种方式表示图形并不重要,因为您从不对属于顶点的边进行排序。而是将所有边放入单个数组中,然后按升序对该数组进行排序。
图表的表示无关紧要,只要你可以走它,并将所有边缘收集到一个数组中(首先,你走图形来计算边缘,然后分配一个足够容量的数组,最后再次遍历图形,将指向边缘的指针放入动态分配的数组中。
一旦指向边缘的指针位于数组中,请对数组进行排序(例如,使用qsort
)并运行Kruskal算法。您需要实施Disjoint Sets才能有效地合并森林;只要您在实现链接列表时没有遇到任何问题,实现不相交的集合应该绝对没有问题。
答案 1 :(得分:0)
您提到的第一个结构是(稀疏)图的标准表示。请注意,您还需要一个权重字段。我会将此作为图表的永久表示,只要它至少是稀疏的。
是的,对于Kruskal来说,你需要一个更像后者的结构,因为你需要一个明确的源顶点。我将为Kruskal定义一个不具有链表的不同结构:
int startPointIndex;
int endPointIndex;
int weight;
你将分配这些结构的数组,用图中的边填充它们,按重量对它们进行排序,然后通过它们扫描端点的不相交的集合联合。