当前位置:文档之家› 最小生成树的Prim算法提高型实验报告

最小生成树的Prim算法提高型实验报告

黄冈师范学院提高型实验报告实验课题最小生成树的Prim算法(实验类型:□综合性■设计性□应用性)实验课程算法程序设计实验时间 2010年12月24日学生姓名周媛鑫专业班级计科 0801学号 200826140110一.实验目的和要求(1)根据算法设计需要, 掌握连通网的灵活表示方法;(2)掌握最小生成树的Prim算法;(3)熟练掌握贪心算法的设计方法;二.实验条件(1)硬件环境:实验室电脑一台(2)软件环境:winTC三.实验原理分析(1)最小生成树的定义:假设一个单位要在n个办公地点之间建立通信网,则连通n个地点只需要n-1条线路。

可以用连通的无向网来表示n个地点以及它们之间可能设置的通信线路,其中网的顶点表示城市,边表示两地间的线路,赋于边的权值表示相应的代价。

对于n个顶点的连通网可以建立许多不同的生成树,每一棵生成树都可以表示一个通信网。

其中一棵使总的耗费最少,即边的权值之和最小的生成树,称为最小生成树。

(2)构造最小生成树可以用多种算法。

其中多数算法利用了最小生成树的下面一种简称为MST的性质:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。

若(u,v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则必存在一棵包含边 (u.v)的最小生成树。

(3)普里姆(Prim)算法即是利用MST性质构造最小生成树的算法。

算法思想如下:假设N=(V,{E})和是连通网,TE是N上最小生成树中边的集合。

算法从U={u0}( u0∈V),TE={}开始,重复执行下述操作:在所有u∈U,v∈V-U的边(u, v) ∈E 中找一条代价最小的边(u0, v0)并入集合TE,同时v0并入U,直到U=V为止。

此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树。

四.实验步骤(1)数据结构的设计:采用邻接矩阵的存储结构来存储无向带权图更利于实现及操作:邻接矩阵的抽象数据结构定义:#define INFINITY INT_MAX //最大值#define MAX_ERTEX_NUM 20 //最大顶点数typedef enum {DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向网,无向图} typedef struct Arc Cell{VRType adj ; // VRType 是顶点关系的类型。

对无权图用1和0表示相邻否;InfoType * info; //该弧相关信息的指针}ArcCell ,AdjMatrix [ MAX_VERTEX_NUM][MAX_VERTEX_NUM];Typedef struct {VertexType vexs [ MAX_VERTEX_NUM] ; //顶点向量AdjMatrix arcs ; // 邻接矩阵int vexnum , arcnum ; //图的当前顶点数和弧数GraphKind kind ; // 图的种类标志}Mgraph ;(2)函数设计函数名称函数原型功能描述main() int main(void) 系统调用主函数Huiru() void Huitu () 绘制无向图GraphicVer() void GraphicVer(Graph *G) 输出邻接矩阵prim() void prim(Graph *G) PRIM算法演示(3)实验源代码#include<graphics.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <conio.h>#define MaxVertexNum 50#define INF 32767typedef struct Graphic{char vexs[MaxVertexNum];int edges[MaxVertexNum][MaxVertexNum];int v,e;}Graph;char tmp[10];void Huitu() /*无向图的图形生成*/{char buffer[100];int graphdriver = DETECT, graphmode;int i,xbefore,ybefore;int x1,y1; char c;/*registerbgidriver(EGAVGA_driver);initgraph(&graphdriver, &graphmode, ""); cleardevice();printf("input pot (300<x<610,y<400):\ninput 0 to halt!\n");setfillstyle(1,WHITE);setcolor(WHITE);scanf("%d,%d,%s",&xbefore,&ybefore,buffer);circle(xbefore,ybefore,15);floodfill(xbefore,ybefore,WHITE);setcolor(BLUE);outtextxy(xbefore, ybefore, buffer);setcolor(WHITE);moveto(xbefore,ybefore);while(1){scanf("%d,%d,%s",&x1,&y1,buffer);if(x1==0) break;circle(x1,y1,15);floodfill(x1,y1,WHITE);setcolor(BLUE);outtextxy(x1, y1, buffer);setcolor(WHITE);line(xbefore,ybefore,x1,y1);xbefore=x1;ybefore=y1;}system("pause");}void GraphicVer(Graph *G) /*build and output the adjMatrix*/ {int i,j,k,weight;int v1,v2;printf("input vertex's and edges's number :");scanf("%d,%d",&G->v,&G->e);for(i=1;i<=G->v;i++)for(j=1;j<=G->v;j++)if(i==j) G->edges[i][j]=0;else{ G->edges[i][j]=INF;}for(k=1;k<=G->e;k++){printf("input %dth edge :",k);scanf("%d,%d,%d",&v1,&v2,&weight);G->edges[v1][v2]=G->edges[v2][v1]=weight;}for(i=1;i<=G->v;i++){printf("\n");for(j=1;j<=G->v;j++)printf((G->edges[i][j]==INF)?"∞\t":"%d\t",G->edges[i][j]); } printf("\n");system("pause");}/***************prim 算法生成最小生成树***************/void prim(Graph *G){int lowcost[MaxVertexNum],closest[MaxVertexNum];int i,j,k,min;for(i=2;i<=G->v;i++) /*n个顶点,n-1条边 */ {lowcost[i]=G->edges[1][i];closest[i]=1;}lowcost[1]=0; /*标志顶点1加入U集合*/for(i=2;i<=G->v;i++) /*形成n-1条边的生成树 */ {min=INF; k=0;for(j=2;j<=G->v;j++)if((lowcost[j]<min)&&(lowcost[j]!=0)){min=lowcost[j]; k=j;}printf("(%d,%d)%2d\t",closest[k],k,min);lowcost[k]=0; /*顶点k加入U*/for(j=2;j<=G->v;j++) /*修改由顶点k到其他顶点边的权值*/ if(G->edges[k][j]<lowcost[j]){lowcost[j]=G->edges[k][j];closest[j]=k;}printf("\n");} }void drawwapicture(int lowcost[],int closest[],int vex){ int i=0,x=0,datax=0;setviewport(150,140,630,310,1);cleardevice();setcolor(GREEN);rectangle(10,10,470,160);line(10,60,470,60);line(10,110,470,110);for(i=0;i<vex;i++){x=470-40*i;datax=470-20*i;line(x,10,x,160);if((vex-i)!=0){outtextxy(datax,35,"(vex-i)\0");vsprintf(tmp,"%d",&lowcost[vex-i]);outtextxy(datax,85,tmp);vsprintf(tmp,"%d",&closest[vex-i]);outtextxy(datax,135,tmp);}else{outtextxy(datax,35,"i\0");outtextxy(datax,85,"lowcost\0");outtextxy(datax,135,"closest\0");}}getche();closegraph();}/***************prim 算法生成最小生成树***************/void primyanshi(Graph *G){ void drawwapicture(int *p,int*q,int k);int lowcost[MaxVertexNum],closest[MaxVertexNum];int i,j,k,min;cleardevice();for(i=2;i<=G->v;i++) /*n个顶点,n-1条边 */ { lowcost[i]=G->edges[1][i]; /*初始化*/closest[i]=1; } /*顶点未加入到最小生成树中 */ drawwapicture(lowcost,closest,G->v);lowcost[1]=0; drawwapicture(lowcost,closest,G->v);for(i=2;i<=G->v;i++) /*形成n-1条边的生成树 */ {min=INF; k=0;for(j=2;j<=G->v;j++)if((lowcost[j]<min)&&(lowcost[j]!=0)){min=lowcost[j];k=j;}drawwapicture(lowcost,closest,G->v);cprintf("(%d,%d)%2d\t",closest[k],k,min);lowcost[k]=0; /*顶点k加入U*/drawwapicture(lowcost,closest,G->v);for(j=2;j<=G->v;j++) /*修改由顶点k到其他顶点边的权值*/if(G->edges[k][j]<lowcost[j]){lowcost[j]=G->edges[k][j];closest[j]=k;}drawwapicture(lowcost,closest,G->v);printf("\n");}}int main(){Graph *G=NULL;int flag=1;printf("//****************************************************//\n"); printf("//************Welcome to the world of IRIS************//\n"); printf("/********************************200826140110********//\n"); while(flag!=0){printf("1:Build a Undigraph Net and output the adjMatrix.\n");printf("2.Output the Mini_tree:\n");printf("3.Display the procession of Mini_tree with PRIM:\n");printf("4.exit:\n");scanf("%d",&flag);switch(flag){printf("%d",flag);case 1:Huitu();GraphicVer(G);break;case 2:prim(G);break;case 3: primyanshi(G);break;default :printf("Thank you!\n");system("pause");exit(0);}}printf("Thank you!\n");system("pause"); return 0;}五.实验结果分析六.实验小结通过此次实验后我深刻地学习了最小生成树的Prim算法,通过分析实验目的和实验内容;阐述不同方法的原理;分析不同方法的特点和区别以及时空复杂度;分析和调试测试数据和相应的结果.明白了Prim算法是设计思想:设图G =(V,E),其生成树的顶点集合为U。

相关主题