图的基本操作.docx
《图的基本操作.docx》由会员分享,可在线阅读,更多相关《图的基本操作.docx(13页珍藏版)》请在冰豆网上搜索。
图的基本操作
实验七:
图的基本操作
(1)键盘输入数据,建立一个有向图的邻接表。
(2)输出该邻接表。
(3)在有向图的邻接表的基础上计算各顶点的度,并输出。
(4)以有向图的邻接表为基础实现输出它的拓扑排序序列。
(5)采用邻接表存储实现无向图的深度优先遍历。
(6)采用邻接表存储实现无向图的广度优先遍历。
(7)采用邻接矩阵存储实现无向图的最小生成树的PRIM算法。
(8)采用邻接矩阵存储一个有向图,输出单源点到其它顶点的最短路径。
(9)在主函数中设计一个简单的菜单,分别调试上述算法。
综合训练:
为计算机专业设计教学计划:
4个学年,每学年2个学期,开设50门课程,每学期所开课程门数尽量均衡,课程的安排必须满足先修关系。
#include
#include
#include
#include
usingnamespacestd;
#definemax_vertex_num20
#defineINFINITY1000000000
typedefstructArcNode{
intadjvex;
structArcNode*nextarc;
}ArcNode;
typedefcharvertexType;
typedefstructVNode{
vertexTypedata;
ArcNode*firstarc;
intcount;
}VNode,AdjList[max_vertex_num];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;
intdegree;
}ALGraph;//邻接表
typedefstructArcCell{
intadj;
}ArcCell,AdjMatrix[max_vertex_num][max_vertex_num];
typedefstruct{
charvex[max_vertex_num];
AdjMatrixarc;
intvexnum,arcnum;
}MGraph;//邻接矩阵
ALGraphALG,InsertALG,UALG;
MGraphG;
intvisit[max_vertex_num];
structedge{
charadjvex;
intlowcost;
}closedge[max_vertex_num];
intP[max_vertex_num];
intD[max_vertex_num];
intfinial[max_vertex_num];
voidprint()
{
printf("
(1)键盘输入数据,建立一个有向图的邻接表\n");
printf("
(2)输出该邻接表\n");
printf("(3)在有向图的邻接表的基础上计算各顶点的度,并输出\n");
printf("(4)以有向图的邻接表为基础实现输出它的拓扑排序序列\n");
printf("(5)采用邻接表存储实现无向图的深度优先遍历\n");
printf("(6)采用邻接表存储实现无向图的广度优先遍历\n");
printf("(7)采用邻接矩阵存储实现无向图的最小生成树的PRIM算法\n");
printf("(8)采用邻接矩阵存储一个有向图,输出单源点到其它顶点的最短路径\n");
printf("(0)退出程序\n");
}
intlocatevex(MGraphG,charv)
{//查找顶点在图中的位置
inti=0;
while(i{
if(v==G.vex[i])
break;
else
i++;
}
returni;
}
voidCreateALGraph(ALGraph&ALG,ALGraph&InsertALG)
{//创建有向邻接表及其逆邻接表并且其顶点用大写字母表示
inti,j,k;
ArcNode*s,*r;
printf("请输入有向邻接表的顶点数和边数:
\n");
scanf("%d%d",&ALG.vexnum,&ALG.arcnum);
for(i=0;i{
ALG.vertices[i].data='A'+i;
ALG.vertices[i].firstarc=NULL;
InsertALG.vertices[i].data='A'+i;
InsertALG.vertices[i].firstarc=NULL;
}
for(k=0;k{
scanf("%d%d",&i,&j);
s=(ArcNode*)malloc(sizeof(ArcNode));
r=(ArcNode*)malloc(sizeof(ArcNode));
s->adjvex=j;
s->nextarc=ALG.vertices[i].firstarc;
ALG.vertices[i].firstarc=s;
r->adjvex=i;
r->nextarc=InsertALG.vertices[j].firstarc;
InsertALG.vertices[j].firstarc=r;
}
}
voidCeratUALGraph(ALGraph&UALG)
{//用头插法建立无向邻接表
inti,j,k;
ArcNode*p;
printf("请输入无向邻接表的的顶点数和边数:
\n");
scanf("%d%d",&UALG.vexnum,&UALG.arcnum);
for(i=0;i{
UALG.vertices[i].data='A'+i;
UALG.vertices[i].firstarc=NULL;
}
for(k=0;k{
scanf("%d%d",&i,&j);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=UALG.vertices[i].firstarc;
UALG.vertices[i].firstarc=p;
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=i;
p->nextarc=UALG.vertices[j].firstarc;
UALG.vertices[j].firstarc=p;
}
}
voidCreateUDN(MGraph&G,inta)
{//若a==1的时候创建无向邻接矩阵,否则创建有向邻接矩阵
inti,j,k,w;
charv1,v2;
printf("请输入邻接矩阵的顶点数和边数:
\n");
scanf("%d%d",&G.vexnum,&G.arcnum);
getchar();
for(i=0;iscanf("%c",&G.vex[i]);
for(i=0;ifor(j=0;jG.arc[i][j].adj=INFINITY;
for(k=0;k{
getchar();
scanf("%c%c%d",&v1,&v2,&w);
i=locatevex(G,v1);
j=locatevex(G,v2);
G.arc[i][j].adj=w;
if(a==1)
G.arc[j][i].adj=G.arc[i][j].adj;
}
}
voidshuchu(ALGraphALG)
{//遍历邻接表并输出
inti;
ArcNode*p;
for(i=0;i{
printf("%d%c",i,ALG.vertices[i].data);
for(p=ALG.vertices[i].firstarc;p!
=NULL;p=p->nextarc)
printf("%d",p->adjvex);
printf("\n");
}
}
voidDegree(ALGraphALG,ALGraphInsertALG)
{//计算邻接表的度=邻接表的出度+逆邻接表的的出度
inti;
ArcNode*p;
for(i=0;i{
ALG.vertices[i].count=0;
for(p=ALG.vertices[i].firstarc;p!
=NULL;p=p->nextarc)
ALG.vertices[i].count++;
}
for(i=0;i{
InsertALG.vertices[i].count=0;
for(p=InsertALG.vertices[i].firstarc;p!
=NULL;p=p->nextarc)
InsertALG.vertices[i].count++;
}
for(i=0;i{
printf("%c的度为:
%d\n",'A'+i,ALG.vertices[i].count+InsertALG.vertices[i].count);
}
}
voiddfs(ALGraphUALG,intv)
{//深度优先遍历
ArcNode*p;
visit[v]=1;
printf("%c\n",UALG.vertices[v].data);
p=UALG.vertices[v].firstarc;
while(p)
{
if(!
visit[p->adjvex])
dfs(UALG,p->adjvex);
p=p->nextarc;
}
}
voidDFSTraverse(ALGraphUALG)
{
for(inti=0;ivisit[i]=0;
for(i=0;iif(!
visit[i])
dfs(UALG,i);
printf("\n");
}
voidBFSTraverse(ALGraphUALG)
{//广度优先遍历
ArcNode*p;
intv;
queueq;
for(inti=0;ivisit[i]=0;
for(i=0;iif(!
visit[i]){
visit[i]=1;
printf("%c\n",UALG.vertices[i].data);
q.push(i);
while(!
q.empty())
{
v=q.front();
q.pop();
p=UALG.vertices[v].firstarc;
while(p)
{
if(!
visit[p->adjvex])
{
visit[p->adjvex]=1;
printf("%c\n",UALG.vertices[p->adjvex].data);
q.push(p->adjvex);
}
p=p->nextarc;
}
}
}
}
voidprim(MGraphG,charv)
{//用prim算法求最小生成树
inti,j,k,min,n;
k=locatevex(G,v);
for(i=0;i{
if(i!
=k)
{
closedge[i].adjvex=v;
closedge[i].lowcost=G.arc[k][i].adj;
}
}
closedge[k].lowcost=0;
for(i=1;i{
min=INFINITY;
for(j=0;j{
if(closedge[j].lowcost!
=0&&closedge[j].lowcost{
n=j;
min=closedge[j].lowcost;
}
}
printf("%c%c\n",closedge[n].adjvex,G.vex[n]);
closedge[n].lowcost=0;
for(j=0;jif(G.arc[n][j].adj=INFINITY)
{
closedge[j].adjvex=G.vex[n];
closedge[j].lowcost=G.arc[n][j].adj;
}
}
printf("\n");
}
intindegree[max_vertex_num];
inttopsort(ALGraphALG,ALGraphInsertALG)
{//拓扑排序
ArcNode*p;
stacks;
inti,k,count;
for(i=0;i{
InsertALG.vertices[i].count=0;
for(p=InsertALG.vertices[i].firstarc;p!
=NULL;p=p->nextarc)
InsertALG.vertices[i].count++;
}
for(i=0;i{
indegree[i]=InsertALG.vertices[i].count;
printf("%d\n",indegree[i]);
}
for(i=0;iif(indegree[i]==0)
s.push(i);
count=0;
while(!
s.empty())
{
i=s.top();
s.pop();
printf("%c",ALG.vertices[i].data);
count++;
for(p=ALG.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
indegree[k]--;
if(indegree[k]==0)
s.push(k);
}
}
if(countreturn-1;
else
return1;
}
voidshort_dij(MGraphG,intv0,int*P,int*D)
{//用dij球最短路径
inti,v,w,min;
for(i=0;i{
finial[i]=0;
D[i]=G.arc[v0][i].adj;
if(D[i]P[i]=v0;
}
D[v0]=0;finial[v0]=1;
for(i=1;i{
min=INFINITY;
for(w=0;w{
if(finial[w]==0)
if(D[w]{
v=w;
min=D[w];
}
}
if(minfinial[v]=1;
else
break;
for(w=0;w{
if(finial[w]==0&&min+G.arc[v][w].adj{
D[w]=min+G.arc[v][w].adj;
P[w]=v;
printf("%d",P[w]);
}
}
printf("\n");
}
printf("路径长度为:
\n");
for(i=0;i{
if(D[i]==INFINITY)
printf("无法到达!
!
!
\n");
else
printf("%d\n",D[i]);
}
}
intmain()
{
intmenu;
charV;
do{
voidprint();
scanf("%d",&menu);
switch(menu)
{
case1:
CreateALGraph(ALG,InsertALG);break;
case2:
shuchu(ALG);break;
case3:
CreateALGraph(ALG,InsertALG);Degree(ALG,InsertALG);break;
case4:
CreateALGraph(ALG,InsertALG);topsort(ALG,InsertALG);break;
case5:
CeratUALGraph(UALG);DFSTraverse(UALG);break;
case6:
CeratUALGraph(UALG);BFSTraverse(UALG);break;
case7:
CreateUDN(G,1);printf("请输入出发顶点:
\n");scanf("%c",&V);prim(G,V);break;
case8:
CreateUDN(G,0);short_dij(G,0,P,D);break;
case0:
return0;
}
}while(menu!
=0);
return0;
}