急!数据结构最小生成树prim算法C语言实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了急!数据结构最小生成树prim算法C语言实现相关的知识,希望对你有一定的参考价值。

题目:最小生成树问题 若要在n个城市之间建立通信网络,只需架设n-1条线路即可。如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。 设计要求: 1. 利用普里姆(Prim)算法求网的最小生成树。 2. 使用邻接矩阵(MGraph)存储网的结构。 3. 以文本形式输出最小生成树中的各条边以及他们的权值。 十分感谢!!! 邮箱:494989670@qq.com

参考技术A Kruskal算法:
void
Kruskal(Edge
E[],int
n,int
e)

int
i,j,m1,m2,sn1,sn2,k;
int
vset[MAXE];
for
(i=0;i<n;i++)
vset[i]=i;
//初始化辅助数组
k=1;
//k表示当前构造最小生成树的第几条边,初值为1
j=0;
//E中边的下标,初值为0
while
(k<n)
//生成的边数小于n时循环

m1=E[j].u;m2=E[j].v;
//取一条边的头尾顶点
sn1=vset[m1];sn2=vset[m2];
//分别得到两个顶点所属的集合编号
if
(sn1!=sn2)
//两顶点属于不同的集合,该边是最小生成树的一条边

printf("
(%d,%d):%d/n",m1,m2,E[j].w);
k++;
//生成边数增1
for
(i=0;i<n;i++)
//两个集合统一编号
if
(vset[i]==sn2)
//集合编号为sn2的改为sn1
vset[i]=sn1;

j++;
//扫描下一条边


Prim算法:
void
prim(MGraph
g,int
v)

int
lowcost[MAXV],min,n=g.vexnum;
int
closest[MAXV],i,j,k;
for
(i=0;i<n;i++)
//给lowcost[]和closest[]置初值

lowcost[i]=g.edges[v][i];
closest[i]=v;

for
(i=1;i<n;i++)
//找出n-1个顶点

min=INF;
for
(j=0;j<n;j++)
//在(V-U)中找出离U最近的顶点k
if
(lowcost[j]!=0
&&
lowcost[j]<min)

min=lowcost[j];k=j;

printf("
边(%d,%d)权为:%d/n",closest[k],k,min);
lowcost[k]=0;
//标记k已经加入U
for
(j=0;j<n;j++)
//修改数组lowcost和closest
if
(g.edges[k][j]!=0
&&
g.edges[k][j]<lowcost[j])

lowcost[j]=g.edges[k][j];closest[j]=k;


最小生成树的Prim算法以及Kruskal算法(C语言)

一、最小生成树

  • 连通图生成树包含图中全部顶点的一个极小连通子图。
  • 边尽可能的少,但要保持连通
  • 若图中顶点数为n,则它的生成树含有 n-1 条边。对生成树而言,若砍去它的一条边,则会变成非连通图,若加上一条边则会形成一个回路。

(一)最小生成树(最小代价树)

  • 对于⼀个带权连通⽆向图G = (V, E),⽣成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同。设R为G的所有⽣成树的集合,若T为R中边的权值之和最⼩的⽣成树,则T称为G的最⼩⽣成树(Minimum-Spanning-Tree,MST)
  • 最小生成树可能有多个,但边的权值之和总是唯一且最小的
  • 最小生成树的边数 = 顶点数 - 1。砍掉一条则不连通,增加一条边则会出现回路

(二)Prim 算法(普里姆)

  • Prim 算法(普里姆):从某一个顶点开始构建生成树;每次将代价最小的新顶点纳入生成树,直到所有顶点都纳入为止。
  • P城开始进行建成生成树。
  • 农场开始进行建成生成树。
  • 通过不同的结点开始,建成的最小生成树结构有可能不一样。

(三)Kruskal 算法(克鲁斯卡尔)

  • Kruskal 算法(克鲁斯卡尔):每次选择⼀条权值最⼩的边,使这条边的两头连通(原本已经连通的就不选)直到所有结点都连通。

(四)Prim 算法 v.s. Kruskal 算法

1. Prim 算法的实现思想

  • 初始:从V0开始
  • 第1轮:循环遍历所有个结点,找到lowCost最低的,且还没加⼊树的顶点

  • 第2轮:循环遍历所有个结点,找到lowCost最低的,且还没加⼊树的顶点

  • 第3轮:循环遍历所有个结点,找到lowCost最低的,且还没加⼊树的顶点

  • 第4轮:循环遍历所有个结点,找到lowCost最低的,且还没加⼊树的顶点


  • 第5轮:循环遍历所有个结点,找到lowCost最低的,且还没加⼊树的顶点


2. Kruskal 算法的实现思想

  • 初始:将各条边按权值排序
  • 第1轮:检查第1条边的两个顶点是否连通(是否属于同⼀个集合)
  • 第2轮:检查第2条边的两个顶点是否连通(是否属于同⼀个集合)
  • 第3轮:检查第3条边的两个顶点是否连通(是否属于同⼀个集合)
  • 第4轮:检查第4条边的两个顶点是否连通(是否属于同⼀个集合)
  • 第5轮:检查第5条边的两个顶点是否连通(是否属于同⼀个集合)
  • 第6轮:检查第6条边的两个顶点是否连通(是否属于同⼀个集合)
  • 共执⾏ e 轮,每轮判断两个顶点是否属于同⼀集合,需要 O(log2e)总时间复杂度 O(elog2e)

以上是关于急!数据结构最小生成树prim算法C语言实现的主要内容,如果未能解决你的问题,请参考以下文章

c语言最小生成树

急求KRUSKAL算法求最小生成树过程演示

最小生成树的Prim算法以及Kruskal算法(C语言)

最小生成树与Prim算法

prim和kruscal算法得到的最小生成树是不是一样

技术图文:如何利用C# 实现 Prim 最小生成树算法?