搜档网
当前位置:搜档网 › n个城市最小生成树实验报告材料

n个城市最小生成树实验报告材料

n个城市最小生成树实验报告材料
n个城市最小生成树实验报告材料

数据结构

课程设计报告

起评分理论成绩实践成绩总成绩

院系:

专业:

班级:

学号:

教师:

时间:

目录

一、设计要求 (3)

1、问题描述 (3)

2、功能 (3)

3、数据 (3)

二、概述与分析 (3)

1、图 (3)

2、邻接矩阵 (3)

3、生成树 (4)

4、最小生成树 (5)

5、最小生成树的操作 (5)

三、程序设计及分析 (6)

四、流程图 (7)

1、模块结构流程图 (7)

2、Prim算法流程设计 (8)

五、测试分析 (8)

六、总结 (10)

七、源程序代码 (10)

一、设计要求:

1、问题描述

构造可以使n个城市连接的最小生成树。

2、功能

给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。本人采用的是Prim算法。

3、数据

城市间的距离网采用邻接矩阵表示(要求至少6个城市,10条边),邻接矩阵的存储结构定义采用课本中给出的定义,若两个城市之间不存在道路,则将相应边的权值设为自己定义的无穷大值。要求在屏幕上显示得到的最小生成树中包括了哪些城市间的道路,并显示得到的最小生成树的代价。

表示城市间距离网的邻接矩阵(要求至少6个城市,10条边)

二、概述与分析

1、图

图的定义:图G是有两个集合V和E组成,记做G=(V,E),其中V是定点的有限集合,记做V(G),E是连接V的两个不同的顶点的边的有限集合,记做E(G)。

2、邻接矩阵

邻接矩阵是图的一种存储方法,它是表示顶点之间相邻关系的矩阵。设

G=(V,E)是具有n(n>0)个顶点的图,顶点的顺序依次为(v

0,v

1,…

,v

n-1

),则G的

邻接矩阵A是n阶方阵,其定义如下。

1)如果G是无向图,则

1 (v

i,v

j

) ∈E(G)

A[i][j]=

0 其他

2)如果G是有向图,则

1

i,v

j

> ∈E(G)

A[i][j]=

0其他

3)如果G是带权无向图,则

w ij v

i

≠v

j

且(v

i,

v

j

)∈E(G)

A[i][j]= 0 v

i =v

j

∞其他4)如果G是带权有向图,则

w ij v

i

≠v

j

i,

v

j

> ∈E(G)

A[i][j]= 0 v

i =v

j

∞其他

邻接矩阵的特点如下:

1)图的邻接矩阵表示是唯一的。

2)无向图的邻接矩阵一定是一个对称矩阵。因此,按照压缩存储的思想,在具体存放邻接矩阵是只需要存放上(或下)三角形阵的元素即可。

3)不带权的有向图的邻接矩阵一般是稀疏矩阵,因此,当图的顶点较多时,可以采用三元组表的方法存储邻接矩阵。

4)对于无向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点V

i

的度。

5)对于有向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)

的个数正好是第i个顶点v

i

的出度(或入度)。

6)用邻接矩阵方法存储图,很容易确定图中任意两个顶点之间是否有边相连。但是,要确定图中有多少条边,则必须按行和按列对每个元素进行

检测,所花费的时间大家很大,这是用邻接矩阵存储图的局限性。

3、生成树

一个连通图的生成树是一个极小连通图,它含有图中全部顶点,但只有构成一颗树的(n-1)条边。如果在一颗生成树上添加一条边,必定构成一个环:因为这条边使得它依附的那两个顶点之间有了第2条路径。一颗有n个顶点的生成

树(连通无回路图)有且仅有(n-1)条边,则一定有回路。但是,有(n-1)条边的图不一定都是生成树。

生成树的特点:

1、连通且无环;

2、包含原图中的全部n个顶点,但只有n-1条边;

3、是原图的极小连通子图;

4、最小生成树

对于一个带权(假定每条边上的权值均大于零的实数)连通无向图G中的不同生成树,其每棵树的所有边上的权值之和也可能不同;图的所有生成树中的具有边上的权值之和最小的树成为图的最小生成树。

最小生成树的典型用途:

欲在n个城市间建立通信网. n个城市可能有n(n-1)/2条线路,但铺n-1条线路即可连通;因为每条线路都会有对应的经济成本,那么,如何选择n–1条线路,使总费用最少?

构造数学模型:

顶点———表示城市,有n个;

边————表示线路,有n–1条;

边的权值—表示线路的经济代价;

连通网——表示n个城市间通信网。

5、最小生成树的操作

1、Prim算法:假设G=(V,E)是连通图,T=(U,TE)为欲构造的最小生成树,

初始化U={u0},TE为空,重复以下操作:在所有u∈U,v∈V-U的边(u,v)

∈E中,选择一条权最小的边(u,v)并入TE,同时将v并入U,直到U=V

为止,此时T=(U,TE)是G的一棵最小生成树。

2、在prim算法中需要解决的两个问题:

1)在无向网中,当出现从一个顶点到其它顶点时,若其边上的权值

相等,则可能从某一起点出发时会得出不同的最小生成树,但最

小生成树的权必定都相等,此时我们应该怎样将所有的最小生成

树求解出来;

2)每次如何从生成树T中到T外的所有边中,找出一条最短边。例

如,在第k次(1≤k≤n-1)前,生成树T中已有k个顶点和k-1

条边,此时T中到T外的所有边数为k(n-k),当然它也包括两顶点

间没有直接边相联,其权值被看做常量INF的边在,从如此多的

边中查找最短边,其时间复杂度为O(k(n-k)),显然是很费时的,

是否有一种好的方法能够降低查找最短边的时间复杂度。

三、程序设计及分析

定义结构体和常量

#define MAXV 30

#define INF 32767 //INF 表示无穷大

struct Node

{

int weight;

int vex;//存放顶点编号

int lowcost;//存放顶点权值

};

struct MGraph

{

int vexs[MAXV],n,e; //vexs表示顶点向量;n,e分别表示图的顶点数和边数

Node city[MAXV][MAXV]; //邻接矩阵

};

Node closest[MAXV];// 存放每个顶点所连接的边所对应的权值

1. 函数功能

int Locate(MGraph &g,int V) //求顶点位置函数

MGraph CreateMap(MGraph &g) //创建图

在其函数体中,首先通过键盘输入网中顶点数,若顶点个数<=1时,显示“最小生成树不存在”,然后返回主调函数;否则,继续通过键盘输入网中的边数,通过二重for循环初始化邻接矩阵,然后输入各个顶点的编号及每条边的权值。

int Min(MGraph &g,Node closest[])//closest[]中权值最小的边

void prim(MGraph &g,int u)// 从顶点u出发,按普里姆算法构造连通图g的最小生成树,并输出生成树的每条边

定义一个p用于存放最小生成树中的顶点(按生成最小生成树时的顺序存放),调用函数Locate()求出起点u在顶点向量表中的位置,将u存放到p的顶点向量表中,初始化初始化U={u},利用for循环对V-U中的顶点i,初始化closest[i],再利用for循环找n-1条边(n=g.n),其中,调用函数Min()求出辅助数组closest[]中权值最小的边, 并将其在辅助数组中的相应位置返回到主调函数中并赋给k0,此时closest[k0]中存有当前最小边(u0, v0)的信息,将边所对应的终点放入p的顶点向量表中,累加边的权值;然后,输出;最后,在顶点v0并入U之后,利用for循环更新closest[i];当所有的顶点v0都纳入U 集合之后,输出最小生成树的权值之和。

相关主题