实验五 图的应用(一)
[实验类别]
设计型实验。
[实验目的]
1.熟练掌握图的邻接矩阵和邻接表的存储方式; 2.实现图的一些基本运算,特别是深度遍历和广度遍历; 3.掌握以图为基础的一些常用算法,如最小生成树、拓扑排序、最短路径等。
[实验学时]
2小时
[实验组人数]
1人。
[实验设备环境]
计算机。
[实验内容]
建立一个具有n个结点的无向图的邻接矩阵和邻接表。 (1)、设计一个将邻接矩阵转换为邻接表的算法 (2)、设计一个将邻接表转换为邻接矩阵的算法 (3)、设计以邻接表为存储结构的图的广度优先搜索算法。(选做) (4)、设计以邻接矩阵为存储结构的图的深度优先搜索算法。(选做)
源代码
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std
;
#define Max_Vertex_Num 100
typedef struct
{
char vex
;
char start
;
char endx
;
} Node
;
typedef struct ArcNode
{
int adjvex
;
struct ArcNode
*nextarc
;
int weight
;
} ArcNode
;
typedef struct VNode
{
char vertex
;
ArcNode
*firstarc
;
} VNode
;
typedef VNode AdjList
[Max_Vertex_Num
];
typedef struct
{
AdjList adjlist
;
int vexnum
,arcnum
;
} ALGraph
;
typedef struct
{
char vexs
[Max_Vertex_Num
];
int arcs
[Max_Vertex_Num
][Max_Vertex_Num
];
int vexnum
,arcnum
;
} Mgraph
;
int LocateVex1(Mgraph
&G
,char u
)
{
int i
;
for(i
=0; i
<G
.vexnum
; i
++)
{
if(G
.vexs
[i
]==u
)
return i
;
}
return -1;
}
void CreateMGraph(Mgraph
&G
,int n
,int m
,Node
*q
)
{
int i
,j
,k
;
G
.vexnum
=n
;
G
.arcnum
=m
;
for(i
=0; i
<G
.vexnum
; i
++)
{
G
.vexs
[i
]=q
[i
].vex
;
}
for(i
=0; i
<G
.vexnum
; i
++)
{
for(j
=0; j
<G
.vexnum
; j
++)
{
G
.arcs
[i
][j
]=0;
}
}
for(k
=0; k
<G
.arcnum
; k
++)
{
char v1
=q
[k
].start
;
char v2
=q
[k
].endx
;
i
=LocateVex1(G
,v1
);
j
=LocateVex1(G
,v2
);
if((i
==-1)||(j
==-1))
printf("该条边不存在\n");
else
{
G
.arcs
[i
][j
]=1;
G
.arcs
[j
][i
]=1;
}
}
}
void DispMatrix(Mgraph G
)
{
int i
,j
;
printf(" ");
for(i
=0;i
<G
.vexnum
;i
++)
{
printf("%c ",G
.vexs
[i
]);
}
printf("\n");
for(i
=0; i
<G
.vexnum
; i
++)
{
printf("%c ",G
.vexs
[i
]);
for(j
=0; j
<G
.vexnum
; j
++)
printf("%d ",G
.arcs
[i
][j
]);
printf("\n");
}
}
int LocateVex2(ALGraph
&G
,char u
)
{
int i
;
for(i
=0; i
<G
.vexnum
; i
++)
{
if(G
.adjlist
[i
].vertex
==u
)
return i
;
}
return -1;
}
void CreateALGraph(ALGraph
&G
,int n
,int m
,Node
*q
)
{
ArcNode
*p1
,*p2
;
int i
,j
,k
;
G
.vexnum
=n
;
G
.arcnum
=m
;
for(k
=0; k
<G
.vexnum
; k
++)
{
G
.adjlist
[k
].vertex
=q
[k
].vex
;
G
.adjlist
[k
].firstarc
=NULL;
}
k
=0;
while(k
<G
.arcnum
)
{
char v1
=q
[k
].start
;
char v2
=q
[k
].endx
;
i
=LocateVex2(G
,v1
);
j
=LocateVex2(G
,v2
);
if((i
==-1)||(j
==-1))
printf("该边不存在!\n");
else
{
k
++;
p1
=(ArcNode
*)malloc(sizeof(ArcNode
));
p1
->adjvex
=j
;
p1
->nextarc
=G
.adjlist
[i
].firstarc
;
G
.adjlist
[i
].firstarc
=p1
;
p2
=(ArcNode
*)malloc(sizeof(ArcNode
));
p2
->adjvex
=i
;
p2
->nextarc
=G
.adjlist
[j
].firstarc
;
G
.adjlist
[j
].firstarc
=p2
;
}
}
}
void DispAdjList(ALGraph G
)
{
ArcNode
*p
;
int i
;
for(i
=0; i
<G
.vexnum
; i
++)
{
printf("%c:",G
.adjlist
[i
].vertex
);
for(p
=G
.adjlist
[i
].firstarc
; p
!=NULL; p
=p
->nextarc
)
printf("->%c",p
->adjvex
+'A');
printf("\n");
}
}
void changeAdjlist(Mgraph g
,ALGraph
&G
)
{
int i
,j
;
ArcNode
*p
;
for (i
=0; i
<g
.vexnum
; i
++)
{
G
.adjlist
[i
].vertex
=g
.vexs
[i
];
G
.adjlist
[i
].firstarc
=NULL;
}
for (i
=0; i
<g
.vexnum
; i
++)
for (j
=g
.vexnum
-1; j
>=0; j
--)
if (g
.arcs
[i
][j
]!=0)
{
p
=(ArcNode
*)malloc(sizeof(ArcNode
));
p
->adjvex
=j
;
p
->nextarc
=G
.adjlist
[i
].firstarc
;
G
.adjlist
[i
].firstarc
=p
;
}
G
.vexnum
=g
.vexnum
;
G
.arcnum
=g
.arcnum
;
}
void changeMGraph(Mgraph
&G
,ALGraph g
)
{
int i
;
ArcNode
*p
;
for(i
=0;i
<g
.vexnum
;i
++)
G
.vexs
[i
]=g
.adjlist
[i
].vertex
;
for(i
=0;i
<g
.vexnum
;i
++)
{
p
=g
.adjlist
[i
].firstarc
;
while(p
!=NULL)
{
G
.arcs
[i
][p
->adjvex
]=1;
p
=p
->nextarc
;
}
}
G
.vexnum
=g
.vexnum
;
G
.arcnum
=g
.arcnum
;
}
void BfsALGraph(ALGraph G
,int n
,int v
)
{
ArcNode
*p
;
int i
,j
;
int Q
[n
+1],r
,f
;
int visited
[n
];
for(i
=0;i
<G
.vexnum
;i
++)
{
visited
[i
]=0;
}
r
=0;f
=0;
visited
[v
]=1;
printf("%c",G
.adjlist
[v
].vertex
);
r
=(r
+1)%(n
+1);
Q
[r
]=v
;
while(f
!=r
)
{
f
=(f
+1)%(n
+1);
j
=Q
[f
];
p
=G
.adjlist
[j
].firstarc
;
while(p
!=NULL)
{
if(visited
[p
->adjvex
]==0)
{
printf("->%c",p
->adjvex
+'A');
visited
[p
->adjvex
]=1;
r
=(r
+1)%(n
+1);
Q
[r
]=p
->adjvex
;
}
p
=p
->nextarc
;
}
}
}
void Dfs(Mgraph G
,int i
,int visited
[],int &t
)
{
int j
;
visited
[i
]=1;
if(t
+1==G
.vexnum
)
{
printf("%c",G
.vexs
[i
]);
}
else
{
printf("%c->",G
.vexs
[i
]);
t
++;
}
for(j
=0;j
<G
.vexnum
;j
++)
{
if(G
.arcs
[i
][j
]!=0&&!visited
[j
])
{
Dfs(G
,j
,visited
,t
);
}
}
}
void DFSTraverse(Mgraph G
,int n
,int &t
)
{
int visited
[n
];
int i
;
for(i
=0;i
<G
.vexnum
;i
++)
visited
[i
]=0;
for(i
=0;i
<G
.vexnum
;i
++)
{
if(!visited
[i
])
Dfs(G
,i
,visited
,t
);
}
}
int main()
{
Mgraph G1
,G4
;
ALGraph G2
,G3
;
Node q
[100];
int n
,m
,i
,t
=0;
printf("输入图的信息为(顶点为大写字母):\n");
printf("输入顶点数和边数:\n");
scanf("%d %d",&n
,&m
);
printf("输入每个顶点:\n");
for(i
=0; i
<n
; i
++)
{
getchar();
scanf("%c",&q
[i
].vex
);
}
printf("输入每条边:\n");
for(i
=0; i
<m
; i
++)
{
getchar();
scanf("%c",&q
[i
].start
);
getchar();
scanf("%c",&q
[i
].endx
);
}
printf("输出图的邻接矩阵G1:\n");
CreateMGraph(G1
,n
,m
,q
);
DispMatrix(G1
);
printf("输出图的邻接表G2:\n");
CreateALGraph(G2
,n
,m
,q
);
DispAdjList(G2
);
printf("邻接矩阵G1转换成邻接表G3:\n");
changeAdjlist(G1
,G3
);
printf("转换前邻接矩阵G1:\n");
DispMatrix(G1
);
printf("转换后邻接表G3:\n");
DispAdjList(G3
);
printf("邻接表G2转换成邻接邻阵G4:\n");
changeMGraph(G4
,G3
);
printf("转换前邻接表G2:\n");
DispAdjList(G2
);
printf("转换后邻接矩阵G4:\n");
DispMatrix(G4
);
printf("以邻接表G2为存储结构的图的广度优先搜索:\n");
BfsALGraph(G2
,n
,0);
printf("\n");
printf("以邻接矩阵G1为存储结构的图的深度优先搜索:\n");
DFSTraverse(G1
,n
,t
);
return 0;
}