#include<stdio.h>
#include<stdlib.h>
#define INFINITY INT_MAX /* 最大值∞ */
#define MAX_VEX 20 /* 最大顶点数 */
int Visited[MAX_VEX];/* 标志数组 */
typedef enum{DG,DN,UDG,UDN} Graphkind;
typedef struct{ //包含权的邻接矩阵的的定义
int Vertices[MAX_VEX]; //顶点信息的数组
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum; //当前图的顶点数
int arcnum; //当前的图边数
Graphkind kind;
}MGraph;
//函数声明
void CreateDG(MGraph *G);
void CreateDN(MGraph *G);
void CreateUDG(MGraph *G);
void CreateUDN(MGraph *G);
void DispGraph(MGraph G);
void DFS_traverse_Grapg(MGraph G);
void BFS_traverse_Grapg(MGraph G);
//构造图(选择图的种类)
void CreateGraph(MGraph *G){
while(1){
printf("请输入图的种类(0.有向图 1.有向网 2.无向图 3.无向网):");
scanf("%d",&G->kind);
switch(G->kind) {
case DG:CreateDG(G);break;
case DN:CreateDN(G);break;
case UDG:CreateUDG(G);break;
case UDN:CreateUDN(G);break;
default:printf("输入错误,请从新输入!\n");
}
if(G->kind>=0&&G->kind<=3){
DispGraph(*G);
printf("\n");
DFS_traverse_Grapg(*G);
printf("\n");
BFS_traverse_Grapg(*G);
printf("\n******************************************************\n");
}
}
}
/* 构造时输入弧(边)的顺序会影响打印的邻接表及深、度广度优先搜索 */
//有向图
void CreateDG(MGraph *G) //图的生成函数
{
int vi,vj,w,i,j;
printf("请输入图的顶点数和弧数(以空格分隔):");
scanf("%d%d",&G->vexnum,&G->arcnum);
//图(邻接矩阵)的初始化
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
G->arcs[i][j]=0;
//将顶点存入数组中
for(i=0;i<G->vexnum;i++)
{
printf("请输入第%d个顶点的信息(整型):",i+1);
scanf("%d",&G->Vertices[i]); //以0为位置起点
}
printf("\n");
//将弧存入邻接矩阵中
for(i=0;i<G->arcnum;i++)
{
printf("请输入第%d条弧的信息i,j,w(以空格分隔):",i+1);
scanf("%d%d%d",&vi,&vj,&w);
//vi,vj为边或弧的顶点位置信息
//若为不带权值的图,则w输入1
//若为带权值的图,则w输入对应权值
G->arcs[vi][vj]=w;
}
// DispGraph(*G);
}
//有向网
void CreateDN(MGraph *G) //图的生成函数
{
int vi,vj,w,i,j;
printf("请输入图的顶点数和弧数(以空格分隔):");
scanf("%d%d",&G->vexnum,&G->arcnum);
//图(邻接矩阵)的初始化
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
G->arcs[i][j]=INT_MAX;
//将顶点存入数组中
for(i=0;i<G->vexnum;i++)
{
printf("请输入第%d个顶点的信息(整型):",i+1);
scanf("%d",&G->Vertices[i]);
}
printf("\n");
//将弧存入邻接矩阵中
for(i=0;i<G->arcnum;i++)
{
printf("请输入第%d条弧的信息i,j,w(以空格分隔):",i+1);
scanf("%d%d%d",&vi,&vj,&w);
//若为不带权值的图,则w输入1
//若为带权值的图,则w输入对应权值
G->arcs[vi][vj]=w;
}
// DispGraph(*G);
}
//无向图
void CreateUDG(MGraph *G) //图的生成函数
{
int vi,vj,w,i,j;
printf("请输入图的顶点数和边数(以空格分隔):");
scanf("%d%d",&G->vexnum,&G->arcnum);
//图(邻接矩阵)的初始化
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
G->arcs[i][j]=0;
//将顶点存入数组中
for(i=0;i<G->vexnum;i++)
{
printf("请输入第%d个顶点的信息(整型):",i+1);
scanf("%d",&G->Vertices[i]);
}
printf("\n");
//将边存入邻接矩阵中
for(i=0;i<G->arcnum;i++)
{
printf("请输入第%d条边的信息i,j,w(以空格分隔):",i+1);
scanf("%d%d%d",&vi,&vj,&w);
//若为不带权值的图,则w输入1
//若为带权值的图,则w输入对应权值
G->arcs[vi][vj]=w;//①
G->arcs[vj][vi]=w;//②
//无向图具有对称性的规律,通过①②实现
//有向图不具备此性质,所以只需要①
}
// DispGraph(*G);
}
//无向网
void CreateUDN(MGraph *G) //图的生成函数
{
int vi,vj,w,i,j;
printf("请输入图的顶点数和边数(以空格分隔):");
scanf("%d%d",&G->vexnum,&G->arcnum);
//图(邻接矩阵)的初始化
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
G->arcs[i][j]=INT_MAX;
//将顶点存入数组中
for(i=0;i<G->vexnum;i++)
{
printf("请输入第%d个顶点的信息(整型):",i+1);
scanf("%d",&G->Vertices[i]);
}
printf("\n");
//将边存入邻接矩阵中
for(i=0;i<G->arcnum;i++)
{
printf("请输入第%d条边的信息i,j,w(以空格分隔):",i+1);
scanf("%d%d%d",&vi,&vj,&w);
//若为不带权值的图,则w输入1
//若为带权值的图,则w输入对应权值
G->arcs[vi][vj]=w;//①
G->arcs[vj][vi]=w;//②
//无向网具有对称性的规律,通过①②实现
//有向网不具备此性质,所以只需要①
}
// DispGraph(*G);
}
//输出邻接矩阵的信息
void DispGraph(MGraph G)
{
int i,j;
printf("\n输出顶点的信息(整型):");
for(i=0;i<G.vexnum;i++)
printf("%8d",G.Vertices[i]);
printf("\n输出邻接矩阵:\n");
printf("\t");
for(i=0;i<G.vexnum;i++)
printf("%8d",G.Vertices[i]);
printf("\n");
for(i=0;i<G.vexnum;i++)
{
printf("\n%8d",G.Vertices[i]);
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[i][j]==INFINITY){
printf("%8s","∞");
}
else{
printf("%8d",G.arcs[i][j]);
}
}
printf("\n");
}
}
void Visit(int v)
{
printf("\t%d",v);
}
/* 深度优先搜索(邻接矩阵) */
void DFS(MGraph G , int v)
{ int i;
Visit(v); /* 访问顶点v */
Visited[v]=1; //设置访问标志
for(i=0;i<G.vexnum;i++){
if((G.arcs[v][i]>=1&&G.arcs[v][i]!=INT_MAX)&&Visited[i]==0){ //G.arcs[v][i]==1只针对图,对网无效
DFS(G,i);
}
}
}
void DFS_traverse_Grapg(MGraph G)
{ int v;
for (v=0 ; v<G.vexnum ; v++)
Visited[v]=0; /* 访问标志初始化 */
//p=G->AdjList[v].firstarc;
printf("深度优先搜索遍历:");
DFS(G , 0);
// for (v=0 ; v<G.vexnum ; v++){
// if (!Visited[v]) /* 对图的每个顶点至多调用一次DFS函数 */
// DFS(G , v);
// }
}
/* 广度优先搜索(邻接矩阵) */
void BFS_traverse_Grapg(MGraph G){
int Queue[MAX_VEX];
int front=0,rear=0;
int i,k,v,w;
for(v=0;v<G.vexnum;v++){
Visited[v]=0;
}
printf("广度优先搜索遍历:");
for(i=0;i<G.vexnum;i++){ /* 连通图仅需从一个1顶点出发即可 */
v=G.Vertices[i]; /* 取顶点 */
if(!Visited[v]){ /* v尚未访问 */
Queue[++rear]=v; /* v入对 */
}
while (Queue[front]!=Queue[rear]){ /* 队列非空时 */
w=Queue[++front]; /* 出队 */
Visited[w]=1; /* 置访问标志 */
Visit(w); /* 访问队首元素 */
for(k=0;k<G.vexnum;k++){
if((G.arcs[v][i]>=1&&G.arcs[v][i]!=INT_MAX)&&Visited[i]==0){ /* 当前顶点未被访问的所有邻结点入队 */
Queue[++rear]=k;
}/* end if */
}/* end for */
}/* end while */
}/* end for */
}
void main()
{
MGraph G;
CreateGraph(&G);
}
数据结构图的邻接矩阵存储及深度广度优先搜索
于 2022-02-11 10:40:45 首次发布