数据结构中关于最小生成树的步骤

#include

克鲁斯卡尔算法 克鲁斯卡尔算法的时间复杂度克鲁斯卡尔算法 克鲁斯卡尔算法的时间复杂度


克鲁斯卡尔算法 克鲁斯卡尔算法的时间复杂度


#define INFINITY 100000//相当于无穷大

#define MAX_VERTEX_NUM 20//最多能有多少个点

//邻接矩阵图

char vexs[MAX_VERTEX_NUM];

int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

int vexnum,arcnum;

//保存路径起始点,终点,以及权值

int adjvex;

int enex;

}closedge[MAX_VERTEX_NUM];

void CreateUDN(MGraph &G);

//找到输入字符对应的数字

int LocateVex(MGraph G,char v);

//输出邻接矩阵图

void PrintUDN(MGraph G);

void MiniSpanTree_PRIM(MGraph G,closedge &minedge);

//输出最小生成树的每条边的起点,终点和权值

void PrintMinEdge(MGraph G,closedge minedge);

int main()

closedge minedge;

CreateUDN(G);

printf("该图的邻接矩阵存储示意图如下:n");

PrintUDN(G);

printf("n");

MiniSpanTree_PRIM(G,minedge);

printf("该图生成树的边如下:n");

printf("n");

return 0;

void CreateUDN(MGraph &G)

{i比较典型的是Prim算法和Kruskal算法。nt i,j;

char vex1,vexprintf("%dt",G.arcs[i-1][j-1]);2;//起点,终点字符

int weight;

char ch;

printf("请输入有多少个顶点,多少条边:n");

scanf("%d%d",&G.vexnum,&G.arcnum);

scanf("%s",G.vexs);

//初始化都为0

for(i=0;i

for(j=0;j

G.arcs[i][j]=0;

//输入并赋值有路径的

printf("请输入所有边的起点,终点和权值:n");

for(i=0;i

{while((ch=getchar())!='n'); //吸收换行符

scanf("%c%c",&vex1,&vex2);

scanf("%d",&weight);

vex1Index=LocateVex(G,vex1);

vex2Index=LocateVex(G,vex2);

G.arcs[vex1Index][vex2Index]=G.arcs[vex2Index][vex1Index]=weight;

for(i=0;i

{for(j=0;j

if(G.arcs[i][j]==0&&i!=j)

{G.arcs[i][j]=INFINITYint lowcost;;

{int i;

if(v==G.vexs[i])

return i;

}//输出对应矩阵

void PrintUDN(MGraph G)

{int i,j;

for(i=0;i<=G.vexnum;i++)

{for(j=0;j<=G.vexnum;j++)

{if(i==0&&j==0)

printf("t");

else if(i==0)

}else if(j==0)

{printf("%ct",G.vexs[i-1]);

}else

{if(G.arcs[i-1][j-1]==INFINITY)

printf("∞t");

else

printf("n");

int temp;

int currentmin;

//起始初始化

k=0;

for(j=1;j

{minedge[j-1].adjvex=k;

minedge[j-1].enex=j;

minedge[j-1].lowcost=G.arcs[k][j];

}//找最小路径

for(i=0;i

{//找个路径最短的可达点

currentmin=minedge[i].lowcost;

k=i;

for(j=i+1;j

{if(minedge[j].lowcost

{currentmin=minedge[j].lowcost;

k=j;

//做相应作

{temp=minedge[i].adjvex;

minedge[i].adjvex=minedge[k].adjvex;

minedge[k].adjvex=temp;

temp=minedge[i].enex;

minedge[i].enex=minedge[k].enex;

minedge[k].enex=temp;

temp=minedge[i].lowcost;

minedge[i].lowcost=minedge[k].lowcost;

}//依次找后面的可达最小路径

for(j=i+1;j

{z=minedge[i].enex;

if(k!=z)

{if(G.arcs[z][k]

{minedge[j].adjvex=z;

minedge[j].lowcost=G.arcs[z][k];

}//输出最小生成树

void PrintMinEdge(MGraph G,closedge minedge)

{int i;

for(i=0;i

}

怎样用克鲁斯卡尔算法得到最小生成树,并写出在最小生成树中依次得到的各

这样做的正确性可以通过反证法来证明。设存在一个更优的生成树,但是在构建这个生成树的过程中,我们选择了不按照边权值从小到大排序的边。我们可以将这个生成树变换成已按照边权值从小到大排序的边构成的生成树,这个新的生成树的权值要小于原来的生成树。因此,只有按照边权值从小到大排序的边构成的生成树才是最小生成树。

1. (1,2) 3

2. (4,6) 4

3. (1,3) 5

4. (3,6) 9

6void MiniSpanTree_PRIM(MGraph G,closedge &minedge). (3,5)12

7. (4,7)2#include0

普利姆算法或者克鲁斯卡尔算法中如果有等边怎么办

int LocateVex(MGraph G,char v)

不影响啊…没说最小minedge[k].lowcost=temp;生成树一定是的。

PrintMinEdge(G,minedge);

我手机发言,不是很给力。举个最简单的例子,你自己画个等边三角形,标上ABC,可以做出三个最小生成树。而让程序实现的话就是AB,BC了,这和你的结点顺序有关,就是你存图的那矩阵有关。程序中,出现权值一样的,优先选最现出现的,就是顶点或边序号最小的。下个程序自己trace下就明白啦!

最小生成树的两种算法?

5. (2,5){MGraph G;10

Prim算法 和 Kruskal算法

Prim算法逐次将最小权的边和相应顶点加到中,适合于求边稠密的最小生成树;Kruskal算法先将所有边都放入,然后再逐个选择最小权的边,适合于求稀疏的网的最小生成树。

详细过程请参考相关2 3 8资料

Prim算法

Kruskal算法

数据结构克鲁斯卡尔算法求解题过程

}MGraph;

你好,4有两个,应该是错误,影响不大。克鲁斯卡尔算法可以分为以下两步骤

自己按下面的先后过程画图即是生成过程;说明(i,j)是一条连接顶点i和j的一条边;

步 按权重//创建邻接矩阵排序

序号是为了讲解第二步构建最小生成树使用

按权重排序

请点击输入描述

最小生成树构建步骤图

如有算法相关疑问,或需要代码可私聊,

已知一个图如图所示,用克鲁斯卡尔算法计算最小生成树中各边上数值之和为

jrj

4 6 2

1 3 typedef struct{ 3

3 4 4

6 5 给出几个关键点: 7

就是24

谁能说说为什么kruskal算法不能应用于边权为负的情况?而非要用bellman算法

printf("%c%ct%dn",G.vexs[minedge[i].adjvex],G.vexs[minedge[i].enex],minedge[i].lowcost);

你是否弄错了,是单源最短路径的Dijkstra算法不能边权为负值,因为其算法为从当前最小路径长度开始,逐步增加,并且不再回头运算,如果有边权为负值,自然用bellman算法

还有一个可以选择的是Floyd算法,这后面两者的使用前提都是不存在负权回路,原因是一圈转下来变小了,再转一圈就更小了

而Kruskal算法是求最小生成树的,边权为负值什么问题都没}}}//剩下没路径的(当然不包括自己到自己)赋值无穷大有

这是一道数据结构问题,问题如下:对于如下图所示的带权无向图,给出利用普利姆(Prim)算法和克鲁斯卡尔

}}

普利姆(Prim)算法:从顶点0开始构造

(0,1),(0,2),(1,2),(int vex1Index,vex2Index;//字符对应的数字2,5),(5,4)

克鲁斯卡尔算法:

(0,1),(0,2第二步 构建最小生成树),(1,2),(4,5),(2,5)

已知一个如图所示的带权网络图,使用克鲁斯卡尔算法构造该图的最小生成树

}//将输入的字符转换成对应的数字(A-0,B-1,...)

将原图中所有的边按权值从小到大排序;

//生成最小生成树(实则就是记录最小路径的起点,终点,权值)

从权值最小的边开始,如果这条边连接的两个于图G中不在同一个连通分量中,则添加这条边到图G中for(i=0;i

重复3,直至图G中所有的都在同一个连通分量中。

步,连(1,2)

第二步,连(3,4)

第三步,连(2,4)

第四步,连(3,6)或者(1,5)这两条权重都一样先后无所谓

.意志一无向图结构怎么用克鲁斯卡尔算法求最小生成树(用序号标出添加边的次序)

}//创建邻接矩阵

1.图的存储结构非常重要,简单一点的话可以用3个一维数组分别存储边的两个顶点及权值。

2.将边按权值排{printf("%ct",G.vexs[j-1]);序,注意是3个一维数组,排序的时候都要变化。

3.连通分量的检查,可以用树结构表示一个连通分量,用树根表示名字,查找两个顶点是否在同一个连通分量中,printf("请输入顶点向量:n");只要检查他们是否有同一个树根即可。

4.循环找够n-1条边即可。

5.可以参考刘汝佳的算法设计入门经典