图的深度广度遍历和最小生成树PRIM和KRUSCAL算法的实现.docx
- 文档编号:4174864
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:16
- 大小:17.59KB
图的深度广度遍历和最小生成树PRIM和KRUSCAL算法的实现.docx
《图的深度广度遍历和最小生成树PRIM和KRUSCAL算法的实现.docx》由会员分享,可在线阅读,更多相关《图的深度广度遍历和最小生成树PRIM和KRUSCAL算法的实现.docx(16页珍藏版)》请在冰豆网上搜索。
图的深度广度遍历和最小生成树PRIM和KRUSCAL算法的实现
图的深度广度遍历和最小生成树PRIM和KRUSCAL算法的实现
昨天上实验课,偶然看到这个程序,和大家一起共享一下.....
//图的遍历和生成树求解实现
//(邻接矩阵、邻接表—图的深度广度遍历算法的实现和最小生成树PRIM和KRUSCAL算法的实现)
#include
#include
usingnamespacestd;
#defineint_max10000
#defineinf9999
#definemax20
//…………………………………………邻接矩阵定义……………………
typedefstructArcCell
{
intadj;
char*info;
}ArcCell,AdjMatrix[max][max];
typedefstruct
{
charvexs[max];
AdjMatrixarcs;
intvexnum,arcnum;
}MGraph_L;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
intlocalvex(MGraph_LG,charv)//返回V的位置
{
inti=0;
while(G.vexs[i]!
=v)
++i;
returni;
}
intcreatMGraph_L(MGraph_L&G)//创建图用邻接矩阵表示
{
charv1,v2;
inti,j,w;
cout<<"…………创建无向图…………"< (46)不包括“()”"< cin>>G.vexnum>>G.arcnum; for(i=0;i! =G.vexnum;++i) { cout<<"输入顶点"< cin>>G.vexs[i]; } for(i=0;i! =G.vexnum;++i) for(j=0;j! =G.vexnum;++j) { G.arcs[i][j].adj=int_max; G.arcs[i][j].info=NULL; } for(intk=0;k! =G.arcnum;++k) { cout<<"输入一条边依附的顶点和权: (ab3)不包括“()”"< cin>>v1>>v2>>w;//输入一条边依附的两点及权值 i=localvex(G,v1);//确定顶点V1和V2在图中的位置 j=localvex(G,v2); G.arcs[i][j].adj=w; G.arcs[j][i].adj=w; } cout<<"图G邻接矩阵创建成功! "< returnG.vexnum; } voidljjzprint(MGraph_LG)//邻接矩阵的输出 { inti,j; for(i=0;i! =G.vexnum;++i) { for(j=0;j! =G.vexnum;++j) cout< cout< } } intvisited[max];//访问标记 intwe; typedefstructarcnode//弧结点 { intadjvex;//该弧指向的顶点的位置 structarcnode*nextarc;//弧尾相同的下一条弧 char*info;//该弧信息 }arcnode; typedefstructvnode//邻接链表顶点头接点 { chardata;//结点信息 arcnode*firstarc;//指向第一条依附该结点的弧的指针 }vnode,adjlist; typedefstruct//图的定义 { adjlistvertices[max]; intvexnum,arcnum; intkind; }algraph; //…………………………………………队列定义…………………… typedefstructqnode { intdata; structqnode*next; }qnode,*queueptr; typedefstruct { queueptrfront; queueptrrear; }linkqueue; //……………………………………………………………………… typedefstructacr { intpre;//弧的一结点 intbak;//弧另一结点 intweight;//弧的权 }edg; intcreatadj(algraph&gra,MGraph_LG)//用邻接表存储图 { inti=0,j=0; arcnode*arc,*tem,*p; for(i=0;i! =G.vexnum;++i) { gra.vertices[i].data=G.vexs[i]; gra.vertices[i].firstarc=NULL; } for(i=0;i! =G.vexnum;++i) { for(j=0;j! =G.vexnum;++j) { if(gra.vertices[i].firstarc==NULL) { if(G.arcs[i][j].adj! =int_max&&j! =G.vexnum) { arc=(arcnode*)malloc(sizeof(arcnode)); arc->adjvex=j; gra.vertices[i].firstarc=arc; arc->nextarc=NULL; p=arc; ++j; while(G.arcs[i][j].adj! =int_max&&j! =G.vexnum) { tem=(arcnode*)malloc(sizeof(arcnode)); tem->adjvex=j; gra.vertices[i].firstarc=tem; tem->nextarc=arc; arc=tem; ++j; } --j; } } else { if(G.arcs[i][j].adj! =int_max&&j! =G.vexnum) { arc=(arcnode*)malloc(sizeof(arcnode)); arc->adjvex=j; p->nextarc=arc; arc->nextarc=NULL; p=arc; } } } } gra.vexnum=G.vexnum; gra.arcnum=G.arcnum; cout<<"图G邻接表创建成功! "< return1; } voidadjprint(algraphgra)//邻接表输出 { inti; for(i=0;i! =gra.vexnum;++i) { arcnode*p; cout< p=gra.vertices[i].firstarc; while(p! =NULL) { cout< p=p->nextarc; } cout< } } intfirstadjvex(algraphgra,vnodev)//返回依附顶点V的第一个点 //即以V为尾的第一个结点 { if(v.firstarc! =NULL) returnv.firstarc->adjvex; } intnextadjvex(algraphgra,vnodev,intw)//返回依附顶点V的相对于W的下一个顶点 { arcnode*p; p=v.firstarc; while(p! =NULL&&p->adjvex! =w) { p=p->nextarc; } if(p->adjvex==w&&p->nextarc! =NULL) { p=p->nextarc; returnp->adjvex; } if(p->adjvex==w&&p->nextarc==NULL) return-10; } intinitqueue(linkqueue&q)//初始化队列 { q.rear=(queueptr)malloc(sizeof(qnode)); q.front=q.rear; if(! q.front) return0; q.front->next=NULL; return1; } intenqueue(linkqueue&q,inte)//入队 { queueptrp; p=(queueptr)malloc(sizeof(qnode)); if(! p) return0; p->data=e; p->next=NULL; q.rear->next=p; q.rear=p; return1; } intdequeue(linkqueue&q,int&e)//出队 { queueptrp; if(q.front==q.rear) return0; p=q.front->next; e=p->data; q.front->next=p->next; if(q.rear==p) q.rear=q.front; free(p); return1; } intqueueempty(linkqueueq)//判断队为空 { if(q.front==q.rear)return1; return0; } voidbfstra(algraphgra)//广度优先遍历 { inti,e; linkqueueq; for(i=0;i! =gra.vexnum;++i) visited[i]=0; initqueue(q); for(i=0;i! =gra.vexnum;++i) if(! visited[i]) {visited[i]=1; cout< enqueue(q,i); while(! queueempty(q)) { dequeue(q,e); for(we=firstadjvex(gra,gra.vertices[e]);we>=0;we=nextadjvex(gra,gra.vertices[e],we)) { if(! visited[we]) { visited[we]=1; cout< enqueue(q,we); } } } } } intdfs(algraphgra,inti) { visited[i]=1; intwe1; cout< for(we=firstadjvex(gra,gra.vertices[i]);we>=0;we=nextadjvex(gra,gra.vertices[i],we)) { we1=we; if(visited[we]==0) dfs(gra,we); we=we1; } return1; } intdfstra(algraphgra) { inti,j; for(i=0;i! =gra.vexnum;++i) { visited[i]=0; } for(j=0;j! =gra.vexnum;++j) { if(visited[j]==0) dfs(gra,j); } return0; } intbfstra_fen(algraphgra)//求连通分量 { inti,j; for(i=0;i! =gra.vexnum;++i) visited[i]=0; for(j=0;j! =gra.vexnum;++j) { if(visited[j]==0) { dfs(gra,j); cout< } } return0; } typedefstruct { intadjvex; intlowcost; }closedge; intprim(intg[][max],intn)//最小生成树PRIM算法 { intlowcost[max],prevex[max];//LOWCOST[]存储当前集合U分别到剩余结点的最短路径 //prevex[]存储最短路径在U中的结点 inti,j,k,min; for(i=2;i<=n;i++)//n个顶点,n-1条边 { lowcost[i]=g[1][i];//初始化 prevex[i]=1;//顶点未加入到最小生成树中 } lowcost[1]=0;//标志顶点1加入U集合 for(i=2;i<=n;i++)//形成n-1条边的生成树 { min=inf; k=0; for(j=2;j<=n;j++)//寻找满足边的一个顶点在U,另一个顶点在V的最小边 if((lowcost[j] =0)) { min=lowcost[j]; k=j; } printf("(%d,%d)%d\t",prevex[k]-1,k-1,min); lowcost[k]=0;//顶点k加入U for(j=2;j<=n;j++)//修改由顶点k到其他顶点边的权值 if(g[k][j] { lowcost[j]=g[k][j]; prevex[j]=k; } printf("\n"); } return0; } intacrvisited[100];//kruscal弧标记数组 intfind(intacrvisited[],intf) { while(acrvisited[f]>0) f=acrvisited[f]; returnf; } voidkruscal_arc(MGraph_LG,algraphgra) { edgedgs[20]; inti,j,k=0; for(i=0;i! =G.vexnum;++i) for(j=i;j! =G.vexnum;++j) { if(G.arcs[i][j].adj! =10000) { edgs[k].pre=i; edgs[k].bak=j; edgs[k].weight=G.arcs[i][j].adj; ++k; } } intx,y,m,n; intbuf,edf; for(i=0;i! =gra.arcnum;++i) acrvisited[i]=0; for(j=0;j! =G.arcnum;++j) { m=10000; for(i=0;i! =G.arcnum;++i) { if(edgs[i].weight { m=edgs[i].weight; x=edgs[i].pre; y=edgs[i].bak; n=i; } } buf=find(acrvisited,x); edf=find(acrvisited,y); edgs[n].weight=10000; if(buf! =edf) { acrvisited[buf]=edf; cout<<"("< cout< } } } intmain() { algraphgra; MGraph_LG; inti,d,g[20][20]; chara='a'; d=creatMGraph_L(G); creatadj(gra,G); vnodev; cout< 若该图为非强连通图(含有多个连通分量)时"< <<" 最小生成树不存在,则显示为非法值。 "< cout<<"…………………菜单……………………"< cout<<"0、显示该图的邻接矩阵……………………"< cout<<"1、显示该图的邻接表……………………"< cout<<"2、深度优先遍历…………………………"< cout<<"3、广度优先遍历…………………………"< cout<<"4、最小生成树PRIM算法…………………"< cout<<"5、最小生成树KRUSCAL算法………………"< cout<<"6、该图的连通分量………………………"< ints; chary='y'; while(y='y') { cout<<"请选择菜单: "< cin>>s; switch(s) { case0: cout<<"邻接矩阵显示如下: "< ljjzprint(G); break; case1: cout<<"邻接表显示如下: "< adjprint(gra); break; case2: cout<<"广度优先遍历: "; bfstra(gra); cout< break; case3: for(i=0;i! =gra.vexnum;++i) { visited[i]=0; } cout<<"深度优先遍历: "; dfstra(gra); cout< break; case4: for(i=0;i! =G.vexnum;++i) for(intj=0;j! =G.vexnum;++j) g[i+1][j+1]=G.arcs[i][j].adj; cout<<"prim: "< prim(g,d); break; case5: cout<<"kruscal: "< kruscal_arc(G,gra); break; case6: cout<<"连通分量: "; bfstra_fen(gra); break; } cout< y/n: "; cin>>y; if(y=='n') break; } system("pause"); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 深度 广度 遍历 最小 生成 PRIM KRUSCAL 算法 实现