c语言最小生成树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言最小生成树相关的知识,希望对你有一定的参考价值。

题目描述:给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。
功能要求及说明:
(1)城市间的距离网采用邻接矩阵表示,邻接矩阵的存储结构定义采用课本中给出的定义,若两个城市之间不存在道路,则将相应边的权值设为自己定义的无穷大值。要求在屏幕上显示得到的最小生成树中包括了哪些城市间的道路,并显示得到的最小生成树的代价;
(2)表示城市间距离网的邻接矩阵(要求至少6个城市,10条边);并且利用文件对数据进行提取。
(3)输出最小生成树中包括的边及其权值,并显示得到的最小生成树的代价。
(4)采用模块化设计;

参考技术A 我前段时间写了一个。
你自己改改吧。

#include <stdio.h>
#include <math.h>

struct point

double x,y;
;

struct distence

double _distence;
bool islink;
;

static double CaculateDistence(point x,point y)

return sqrt(pow((x.x-y.x),2.0)+pow((x.y-y.y),2.0));


static bool isInGroup(int *group,int value)

for(int i=0;i<10;++i)

if(value==group[i])return true;

return false;


int main()

/* 初始化各个点的值 */
point _point[10]=2.4169,8.2119,4.0391,0.1540,0.9645,0.4302,1.3197,1.6899,9.4205,6.4912,
9.5613,7.3172,5.7521,6.4775,0.5978,4.5092,2.3478,5.4701,3.5316,2.9632;
/* 初始化距离数组 */
distence _distence[10][10]=0.0,0;
////////////////////////////////////////////////////////////////

/* 计算距离 */
int i,j;
for (i=0;i<10;++i)

for(j=0;j<10;++j)

if(i==j)_distence[i][j]._distence=0;
else _distence[i][j]._distence=CaculateDistence(_point[i],_point[j]);


////////////////////////////////////////////////////////////////////

int pointgroup[10]=0;
int size=1;
pointgroup[0]=0;

///////////////////////////////////////////////////////////////
/* 计算最小生成树 */
for(;size<10;)

double dismin=32454.0;
int tmpx=0,tmpy=0;
for(i=0;i<size;++i)

for(j=0;j<10;++j)

if(_distence[pointgroup[i]][j].islink)continue;
else if(pointgroup[i]==j)continue;
else if(_distence[pointgroup[i]][j]._distence<dismin &&
!isInGroup(pointgroup,j))
dismin=
_distence[pointgroup[i]][j]._distence;
tmpx=pointgroup[i];
tmpy=j;

else continue;



_distence[tmpx][tmpy].islink=true;
_distence[tmpy][tmpx].islink=true;
pointgroup[size]=tmpy;
++size;


//////////////////////打印最小生成树//////////////////////////
for(i=0;i<10;++i)

for(int j=0;j<10;++j)

if(_distence[i][j].islink)printf("%d ------ %d\n",i,j);



return 0;
追问

你这也太简单了吧 算法呢

追答

简单?最小生成树书上的核心算法也不过10几行吧。再自己添点不超过100行。

最小生成树的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)

以上是关于c语言最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

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

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

大话数据结构C语言45 最小生成树(普里姆算法)

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

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

C语言数据结构 克鲁斯卡尔算法求无向网的最小生成树。