第十三周项目-验证算法(1-Prim算法)
来源:互联网 发布:java方法名长度 编辑:程序博客网 时间:2024/05/18 00:23
问题及代码:
/*copyright (t) 2016,烟台大学计算机学院*All rights reserved.*文件名称:1.cpp*作者:常锐*完成日期:2016年11月24日*版本号:v1.0*问题描述:运行Prim算法,观察结果并领会其原理及问题求解过程。*输入描述:无*程序输出:测试结果*/
测试用图:
graph.h:
#include <stdio.h>#define MAXV 100 //定义最大顶点数100#define INF 9999 //处理“无穷大”typedef int InfoType; //定义顶点与边的相关信息typedef int Vertex;typedef struct //定义顶点类型{ int no; //顶点编号 InfoType info; //顶点其他信息} VertexType;typedef struct //定义图邻接矩阵类型{ int edges[MAXV][MAXV]; //邻接矩阵边数组 int n; //顶点数 int e; //边数 VertexType vexs[MAXV]; //存放顶点信息} MGraph;typedef struct ANode //定义边节点类型{ int adjvex; //该边终点编号 struct ANode *nextarc; //指向下一条边的指针 InfoType info; //该边相关信息} ArcNode;typedef struct VNode //定义邻接表头节点类型{ Vertex data; //顶点信息 ArcNode *firstarc; //指向第一条边的指针} VNode;typedef VNode AdjList[MAXV]; //AdjList: 邻接表类型typedef struct //定义图邻接表类型{ AdjList adjlist; //邻接表 int n; //图中顶点数 int e; //图中边数} ALGraph;void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵void ArrayToList(int *Arr, int n, ALGraph *&G); //用普通数组构造图的邻接表void MatToList(MGraph g,ALGraph *&G); //将邻接矩阵g转换成邻接表Gvoid ListToMat(ALGraph *G,MGraph &g); //将邻接表G转换成邻接矩阵gvoid DispMat(MGraph g); //输出邻接矩阵gvoid DispAdj(ALGraph *G); //输出邻接表G
graph.cpp:
#include <malloc.h>#include "graph.h"//几点说明://功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)// n - 矩阵的阶数// g - 要构造出来的邻接矩阵数据结构void ArrayToMat(int *Arr, int n, MGraph &g) //用普通数组构造图的邻接矩阵{ int i,j; int edgenum=0; //边数初始化为0 g.n=n; for(i=0;i<g.n;i++) { for(j=0;j<g.n;j++) { g.edges[i][j]=Arr[i*n+j]; //计算存储位置 if(g.edges[i][j]!=0 && g.edges[i][j]!=INF) edgenum++; } } g.e=edgenum;}void ArrayToList(int *Arr, int n, ALGraph *&G) //用普通数组构造图的邻接表{ int i,j; int edgenum=0; //边数初始化为0 ArcNode *p; //后续操作中创建的新节点 G=(ALGraph *)malloc(sizeof(ALGraph)); G->n=n; for(i=0;i<n;i++) //邻接表所有头节点指针域置初值 G->adjlist[i].firstarc=NULL; for(i=0;i<n;i++) //遍历邻接矩阵中的每个元素 { for(j=n-1;j>=0;j--) { if(Arr[i*n+j]!=0) { p=(ArcNode *)malloc(sizeof(ArcNode)); //创建节点*p p->adjvex=j; p->info=Arr[i*n+j]; p->nextarc=G->adjlist[i].firstarc; //头插法插入*p G->adjlist[i].firstarc=p; //指向第一条边的指针指向*p } } } G->e=edgenum;}void MatToList(MGraph g,ALGraph *&G) //将邻接矩阵g转换成邻接表G{ int i,j; ArcNode *p; G=(ALGraph *)malloc(sizeof(ALGraph)); for(i=0;i<g.n;i++) //给邻接表所有头节点的指针域置初值 G->adjlist[i].firstarc=NULL; for(i=0;i<g.n;i++) //遍历邻接矩阵中的每个元素 { for(j=g.n-1;j>=0;j--) { if(g.edges[i][j]!=0) { p=(ArcNode *)malloc(sizeof(ArcNode)); //创建一个节点*p p->adjvex=j; //终点编号赋值 p->nextarc=G->adjlist[i].firstarc; //头插法插入节点*p G->adjlist[i].firstarc=p; //连接 } } } G->n=g.n; G->e=g.e;}void ListToMat(ALGraph *G,MGraph &g) //将邻接表G转换成邻接矩阵g{ //前提要求:g的实参调用前已经初始化为全0 int i; ArcNode *p; for(i=0;i<G->n;i++) { p=G->adjlist[i].firstarc; //*p指向每个顶点的第一条边 while(p!=NULL) //依次遍历 { g.edges[i][p->adjvex]=1; //p不为空指针时对应矩阵元素赋值1 p=p->nextarc; //*p指向下一条边 } } g.n=G->n; g.e=G->e;}void DispMat(MGraph g) //输出邻接矩阵g{ int i,j; for(i=0;i<g.n;i++) { for(j=0;j<g.n;j++) if(g.edges[i][j]==INF) printf("%3s","∞"); else printf("%3d",g.edges[i][j]); printf("\n"); }}void DispAdj(ALGraph *G) //输出邻接表G{ int i; ArcNode *p; for (i=0; i<G->n; i++) { p=G->adjlist[i].firstarc; printf("%3d: ",i); while (p!=NULL) { printf("-->%d/%d ",p->adjvex,p->info); p=p->nextarc; } printf("\n"); }}
main.cpp:
#include <stdio.h>#include <malloc.h>#include "graph.h"void Prim(MGraph g,int v){ int lowcost[MAXV]; //顶点i是否在U中 int min; int closest[MAXV],i,j,k; for (i=0; i<g.n; i++) //给lowcost[]和closest[]置初值 { lowcost[i]=g.edges[v][i]; closest[i]=v; } for (i=1; i<g.n; i++) //找出n-1个顶点 { min=INF; for (j=0; j<g.n; j++) //在(V-U)中找出离U最近的顶点k if (lowcost[j]!=0 && lowcost[j]<min) { min=lowcost[j]; k=j; //k记录最近顶点的编号 } printf(" 边(%d,%d)权为:%d\n",closest[k],k,min); lowcost[k]=0; //标记k已经加入U for (j=0; j<g.n; j++) //修改数组lowcost和closest if (g.edges[k][j]!=0 && g.edges[k][j]<lowcost[j]) { lowcost[j]=g.edges[k][j]; closest[j]=k; } }}int main(){ MGraph g; int A[6][6]= { {0,10,INF,INF,19,21}, {10,0,5,6,INF,11}, {INF,5,0,6,INF,INF}, {INF,6,6,0,18,14}, {19,INF,INF,18,0,33}, {21,11,INF,14,33,0} }; ArrayToMat(A[0], 6, g); printf("最小生成树构成:\n"); Prim(g,0); return 0;}
运行结果:
知识点总结:
Prim算法
心得体会:
Prim算法:逐个加入顶点,体现了“贪心策略”(即从选定的顶点开始,依次加入权值最小出边对应的顶点),注意不能形成回路。
0 0
- 第十三周项目-验证算法(1-Prim算法)
- 第十三周项目1Prim 算法验证
- 第十三周项目1-Prim算法验证
- 第十三周项目1---(1)Prim算法的验证
- 第十三周项目一(1)Prim算法的验证
- 第十三周项目(1)Prim算法的验证
- 第十三周 项目 1 - 验证算法之Prim算法
- 第十三周 项目一-验证Prim算法
- 第十三周上机实践—项目1—验证算法(1)Prim算法的验证
- 第十三周实践项目—验证算法(1)Prim算法的验证
- 第十三周项目1—验证算法(prim算法,kruskal算法)
- 第十三周项目1--Prim算法的验证
- 第十三周项目1-Prim算法的验证
- 第十三周 项目1-prim算法的验证
- 第十三周项目1-Prim算法的验证
- 第十三周项目1Prim算法的验证
- 第十三周项目1-prim算法的验证
- 第十三周项目1-Prim算法的验证
- Android Launcher3 Shortcut 包名两行显示相切的问题。
- 第十三周项目四(Floyd算法实现)
- java.lang.IllegalArgumentException: java.net.UnknownHostException: user 错误解决
- 第十三周-项目一 验证算法(4)
- 第十一周项目2 用二叉树求解代数表达式
- 第十三周项目-验证算法(1-Prim算法)
- kvm随笔(一)
- 第十三周项目1-prim算法的验证
- 第十三周项目2-Kruskal算法的验证
- ORA-00845: MEMORY_TARGET not supported on this system(解决方法)
- 跨平台Socket封装——对IPv4地址的封装
- mvn 指定Jdk版本,添加仓库,添加代理
- Bootstrap3 栅格系统-实例:移动设备和桌面屏幕
- iOS -- 倒计时获取验证码