【报告】最小生成树算法实验报告

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【关键字】报告

最小生成树算法

➢问题描述

设G=(V,E)是一个无向连通带权图,E中每条边(v,w)的权为c(v,w)。如果G的一个子图G`是一棵包含G的所有顶点的书,则称G`为G的生成树。生成树上各边权的总和称为该生成树的耗费,在G的所有生成树中,耗费最小的生成树就称为G的最小生成树。给定一个无向连通带权图,构造一个最小生成树。

➢设计思想

利用Prim算法求最小生成树,Prim算法是利用贪心策略设计的算法。设G=(V,E)是一个连通带权图,V={1,2,…,n}。构造G的一棵最小生成树的Prim算法的基本思想是:首先置U={1},然后,只要U是V的真子集,就做如下的贪心选择:选取满足条件i∈U,j∈V-U,且使c(i,j)达到最小的边(i,j),并将顶点j添加到U中。这个过程一致进行到U=V时为止。在这个过程中选取到的所有边恰好构成G的一棵最小生成树。

➢时间复杂度

Prim算法的Pascal语言描述如下:

Procedure PRIM(c:array[1..n,1..n] of real);

Var

lowcost:array[1..n] of real;

closest:array[1..n] of integer;

i,j,k,min,integer;

begin

(1)for i:=2 to n do

(2)begin{初始化,此时U只含有顶点1}

(3)lowcost[i]:=c[1,i];

(4)Closest[i]:=1;

(5)end;

(6)for i:=2 to n do

(7)begin {寻找顶点分别在V-U与U中边权最小的边}

(8)min:=lowcost[i];

(9)j:=i;

(10)For k:=2 to n do

(11)If lowcost[k]

(12)Begin

(13)Min:=lowcost[k];

(14)j:=k;

(15)End;

(16)print(j,closest[j]);{输出找到的边}

(17)Lowcost[j]:=∞;{将j添加到U}

(18)For k:=2 to n do {调整lowcost和closest}

(19)if(c[j,k]

(20)Begin

(21)Lowcost[k]:=c[j,k];

(22)Closest[k]:=j;

(23)End

(24)End

(25)End;{PRIM}

上述过程中第(6)~(24)行的for循环要执行n-1次,每次执行时,第(10)~(15)行和第

(18)~(23)行的for循环都要O(n)时间,所以Prim算法所需的计算时间为O(n)。➢实验源代码

图定义头文件Graph.h:

const int MaxV=10;//最多顶点数

const int MaxValue=99;//最大权值

//定义边集数组中的元素类型

struct RCW

{int row,col;

int weight;

};

class adjMList

{

private:

int numE;//当前边数

int GA[MaxV][MaxV];//定义邻接矩阵

public:

//构造函数,初始化图的邻接矩阵与边集数组

adjMList(RCW GE[],int n,int e);

//建立无向带权图的邻接矩阵

void CreateMatrix(int n,int &e,RCW r[]);

//输出边集数组中的每条边

void OutputEdgeSet(RCW ge[],int e);

//根据图的邻接矩阵生成图的边集数组

void ChangeEdgeSet(RCW GE[],int n,int e);

//按升序排列图的边集数组

void SortEdgeSet(RCW GE[],int e);

//利用普里姆算法从顶点v0出发求出用邻接矩阵GA表

//示的图的最小生成树,最小生成树的边集存于数组CT中

void Prim(RCW CT[],int n);

//检查输入的边序号是否越界,若越界则重输

void Check(int n, int& i, int& j);

};

图实现文件Graph.cpp

// 杨松 Graph.cpp

#include"Graph.h"

//构造函数,初始化图的邻接矩阵与边集数组

adjMList::adjMList(RCW GE[],int n,int e)

{int i,j;

for(i=0; i

for(j=0; j

if(i==j) GA[i][j]=0;

else GA[i][j]=MaxValue;

for(i=0;i

numE=0;

}

//输出边集数组中的每条边

void adjMList::OutputEdgeSet(RCW ge[],int e)

{int i,k=0;

cout<<"{";

for(i=0; i<=e-2; i++)

if(ge[i].weight>0){k++;

cout<<'('<

cout<<','<

if(k%5==0) cout<

if(e>0&&ge[i].weight>0) {

cout<<'('<

cout<<','<

cout<<'}'<

}

//建立无向带权图的邻接矩阵

void adjMList::CreateMatrix(int n,int &e,RCW r[])

{int i,j,k=0,w;

cout<<"依次输入无向带权图的每条边的起点和终点"<

//cin>>i>>j>>w;

Check(n,i,j);

if(k==e-1) break;

GA[i][j]=GA[j][i]=w;k++;

}while(1);

numE=e=k;

cout<<"邻接矩阵:\n";

for(i=0;i

{for(j=0;j

cout<

cout<

}

//检查输入的边序号是否越界,若越界则重输

void adjMList::Check(int n, int& i, int& j)

{while(1) {

if(i<0 || i>=n ||j<0 || j>=n)

cout<<"输入有误,请重输!";

相关文档
最新文档