C语言-图的邻接矩阵的建立,广度优先搜索和深度优先搜索
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<memory.h>
#include<stdlib.h>
#define MAX_VETEX_NUM 10
#define OK 1
#define ERROR -1
typedef char VertexType;
typedef int VRType;
typedef int InfoType;
typedef enum {DG,DN,UDG,UDN}GraphKind;
typedef int Status;
#define INFINITY INT_MAX
typedef enum { FALSE, TRUE }Bool;
Bool visited[MAX_VETEX_NUM]; //访问标志数组
Status(*VisitFunc)(int v); //函数变量
typedef struct {
VRType adjvex; //VRType 是顶点关系类型,对无权图用1或0
//表示相邻否,对带权图,则为权值类型
InfoType *IncInfo; //该弧相关信息的指针
}ArcCell,adjMatrix[MAX_VETEX_NUM][MAX_VETEX_NUM];
typedef struct {
VertexType vecx[MAX_VETEX_NUM]; //顶点向量
adjMatrix arcs; //邻接矩阵
int vexnum, arcnum; //图的当前顶点数和弧数
GraphKind kind; //图的种类标志
}MGraph;
//初始条件:图G存在。
//操作结果:若G中存在顶点v,则返回该地点在图中的位置,否则返回-1;
int Locate_vex(MGraph G, VertexType v);
//初始条件:图G存在,v是图中某个点。
//操作结果:返回v的第一个邻接点,若顶点没有邻接点,则返回-1;
Status FirstAdjVex(MGraph G, int v);
//初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点。
//操作结果:返回v的(相对于w)下一个邻接顶点。若w是v的最后一个邻接点,则返回-1;
Status NextAdjVex(MGraph G, int v, int w);
//初始条件:图G存在。
//操作结果:对图进行深度优先遍历。
void DFSTraverse(MGraph G);
//初始条件:
//操作结果:创建无向图。
Status CreateUDG(MGraph *G);
//初始条件:图G存在
//操作结果:打印图中的顶点信息。
void printMGraph(MGraph *G);
//初始条件:图G存在
//操作结果:用数组模拟队列,进行广度优先遍历
void BFSTraverse(MGraph G);
//初始条件:
//操作结果:采用数组表示法,构造无向网
Status CreateUDN(MGraph *G);
//初始条件:
//操作结果:构造图
Status CreateGraph(MGraph *G);
int Locate_vex(MGraph G, VertexType v)
{
int i;
for (i = 0; i < G.vexnum; i++)
{
if (v == G.vecx[i])
return i;
}
return -1;
}
Status CreateUDN(MGraph *G)
{//采用数组表示法,构造无向网
int IncInfo,i,j,k,w;
char v1, v2;
scanf("%d%d%d", &G->vexnum, &G->arcnum,&IncInfo); //IncInfo为0则各弧不含信息
for (i = 0; i < G->vexnum; i++)
scanf("%c", G->vecx[i]); //构造顶点向量
for (i = 0; i < G->vexnum; i++)
for (j = 0; j < G->vexnum; j++)
G->arcs[i][j] = { INFINITY,NULL }; //初始化邻接矩阵
for (k = 0; k < G->arcnum; k++)
{
scanf("%c%c%d", &v1, &v2, &w); //输入一条边依附的顶点及权值
i = Locate_vex(*G, v1); //确定v1 v2在G中的位置
j = Locate_vex(*G, v2); //确定v1 v2在G中的位置
G->arcs[i][j].adjvex = w; //弧<v1,v2>的权值
G->arcs[j][i] = G->arcs[i][j]; //置<v1,v2>的对称弧<v2,v1>
}
return OK;
}
Status CreateUDG(MGraph *G)
{//创建无向图
int i, j, k;
char v1, v2;
printf("输入邻接矩阵的顶点数和弧数及其他相关信息:");
scanf("%d%d", &G->vexnum, &G->arcnum);
getchar();
printf("输入领接矩阵的顶点信息\n");
for (i = 0; i < G->vexnum; i++)
{
scanf(" %c", &G->vecx[i]);
getchar();//接收回车符
}
for (i = 0; i < G->vexnum; i++)
for (j = 0; j < G->vexnum; j++)
G->arcs[i][j] = { 0,NULL }; //对邻接矩阵进行初始化
for (k = 0; k < G->arcnum; k++)
{
printf("输入边的顶点及其其他相关信息:");
scanf(" %c %c", &v1, &v2);
getchar();
i = Locate_vex(*G, v1); //获得顶点信息
j = Locate_vex(*G, v2); //获得顶点信息
G->arcs[i][j] = { 1,NULL };
G->arcs[j][i] = G->arcs[i][j];
}
return OK;
}
Status FirstAdjVex(MGraph G, int v)
{
int i;
for (i = 0; i < G.vexnum; i++)
if (G.arcs[v][i].adjvex != 0)
return i;
return -1;
}
Status NextAdjVex(MGraph G, int v, int w)
{
int i = 0;
for (i = w + 1; i< G.vexnum;i++)
if (G.arcs[v][i].adjvex != 0)
return i;
return -1;
}
void DFS(MGraph G,int v)
{//从第v个顶点出发,递归地深度优先遍历图G
int w;
visited[v] = TRUE;
printf("%c ", G.vecx[v]); //访问第v个顶点
for (w = FirstAdjVex(G, v);w>0; w = NextAdjVex(G, v, w))
if (!visited[w])
DFS(G, w); //对v的尚未访问的顶点调用DFS
}
void DFSTraverse(MGraph G)
{//对图G做深度优先遍历
int i;
//VisitFunc = Visit;
for (i = 0; i < G.vexnum;i++)
visited[i] = FALSE; //访问标志数组初始化
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
DFS(G, i); //对尚未访问的顶点调用DFS
}
}
}
void printMGraph(MGraph *G)
{
int i, j;
printf("\t");
for (i = 0; i < G->vexnum; i++)
printf("%c\t", G->vecx[i]);
for (i = 0; i < G->vexnum; i++)
{
printf("\n%c\t", G->vecx[i]);
for (j = 0; j < G->vexnum; j++)
printf("%d\t", G->arcs[i][j].adjvex);
}
}
void BFSTraverse(MGraph G)
{
VertexType queue[MAX_VETEX_NUM] = {0}; //定义并初始化queue数组,模拟队列
int top = 0; //模拟队列顶部指针
int bottom = 0; //模拟队列底部指针
int v,w,i;
VertexType u;
for (v = 0; v < G.vexnum; v++)
visited[v] = FALSE;
for (v = 0; v<G.vexnum; v++)
{
if (!visited[v]) //v尚未访问
{
visited[v] = TRUE;
printf("%c ", G.vecx[v]);
queue[top++] = G.vecx[v]; //v入队列
}
while (top<5)
{
u = queue[bottom++]; //元素出队列
i = Locate_vex(G, u); //定位元素位置
for(w=FirstAdjVex(G,i);w>=0;w=NextAdjVex(G,i,w))//w为u尚未访问的邻接顶点
if (!visited[w]&&w<G.vexnum)
{
visited[w] = TRUE;
printf("%c ", G.vecx[w]);
queue[top++] = G.vecx[w]; //顶点入队
}
}
}
}
Status CreateGraph(MGraph *G)
{//采用数组(邻接矩阵)表示法,构造图G
scanf("%d", &G->kind);
switch (G->kind) {
case UDG:CreateUDG(G); //创建无向图
break;
case UDN:CreateUDN(G); //创建无向网
break;
default:return ERROR;
}
}
int main()
{
MGraph *G = (MGraph*)malloc(sizeof(MGraph));//创建图 指针G,并分配空间
CreateGraph(G);
//CreateUDG(G);
printMGraph(G);
printf("\n深度优先搜索\n");
DFSTraverse(*G);
printf("\n广度优先搜索\n");
BFSTraverse(*G);
}