最小生成树——Kruskal算法

啦啦啦~~~笔者又回来了。今天给诸位带来的是这段时间笔者在coursera上面跟着北大的老师学离散的时候学到的最小生成树里面的一种叫Kruskal算法,除此以外还有Prim算法(但是笔者还没有弄懂)

首先理清几个离散数学上面的几个概念

①连通图:在无向图中,若任意两个点和都有路径相通,则称该无向图为连通图

②赋权图:每条边都有一个非负实数对应的图。这个实数称为这条边的权。

③生成子图:设G=,G’=是两个图,若V’V,E’E,则称GG的子图,GG的母图,记作G’G.G’GV’=V,则称GG的生成子图

④生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,且又n-1条边构成一棵树

⑤最小生成树:在赋权图中,使得最终权值最小的生成树被称为最小生成树

接下来介绍Kruskal算法的中心思想

Kruskal算法的中心思想就是每次取权尽可能小的边,只要它与已取的边不构成回路,直到取得一棵生成树为止,这也叫避圈法。

然后就是介绍Kruskal算法的操作步骤:
输入:n阶无向连通带权图G=,其中E=

输出:G的最小生成树T

(1)按权从小到大排列边,不妨设W(e1)W(e2)....W(em)

(2)T←Øi←1,k←0.

(3)eiT中的边不构成回路,则令T←T{e1},k←k+1/若条件成立,则取ei,否则弃去ei

(4)k,则令i←i+1,转(3.

如图就是一个最小生成树的示例

最小生成树——Kruskal算法_第1张图片

下面是代码展示

这个算法的主要难点就是如何去判断回路

在参考了其他博主的代码后,发现有很多是应用了指针来实现的,如下

int Find(int *parent,int f)
 { 
while(parnet[f]>0) f = parent[f] 
return f; 
}

下面就是完整的代码展示

int Find(int *parent,int f)
{
    while(parnet[f]>0)
        f = parent[f]
    return f;
}

Typedef struct
{
    int begin;
    int end;
    int weight;
}Edge;

void Kruskal(MGraph g)
{
    Edge E[MaxSize];
    int vset[MaxSize];
    int i,k,j;
    for(i=0;i

P.S.文章中所有离散数学概念来自清华大学出版社屈婉玲等人编著的《离散数学》第五版,代码来自博客http://blog.csdn.net/qq122627018/article/details/51912324

你可能感兴趣的:(最小生成树——Kruskal算法)