使用邻接表广度优先搜索图,判断是否存在由顶点vi到vj的路径
数据结构:
typedef int VertexData;//顶点数据为整型
typedef struct ArcNode
{
int adjvex;//该弧指向顶点的位置
struct ArcNode *nextarc;//指向下一条弧的指针
} ArcNode;
typedef struct VertexNode
{
VertexData data;//顶点数据
ArcNode *firstarc;//指向该顶点第一条弧的指针
} VertexNode;
typedef struct
{
VertexNode vertex[MAX_VERTEX_NUM];
int vernum, arcnum;//图的顶点数和弧数
} AdjList;//基于邻接表的图(Adjacency List Graph)
typedef struct
{
int elem[MAX_VERTEX_NUM];
int front;
int rear;
} SeqQueue;//循环队列,elem[i]存放的值m表示数组位置为m的图的顶点,不是图的顶点的值
完整代码,关键算法有较为详细的注释:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_VERTEX_NUM 1000//最多顶点个数
typedef int VertexData;//顶点数据为整型
typedef struct ArcNode
{
int adjvex;//该弧指向顶点的位置
struct ArcNode *nextarc;//指向下一条弧的指针
} ArcNode;
typedef struct VertexNode
{
VertexData data;//顶点数据
ArcNode *firstarc;//指向该顶点第一条弧的指针
} VertexNode;
typedef struct
{
VertexNode vertex[MAX_VERTEX_NUM];
int vernum, arcnum;//图的顶点数和弧数
} AdjList;//基于邻接表的图(Adjacency List Graph)
typedef struct
{
int elem[MAX_VERTEX_NUM];
int front;
int rear;
} SeqQueue;//循环队列,elem[i]存放的值m表示数组位置为m的图的顶点,不是图的顶点的值
int visited[MAX_VERTEX_NUM];
int LocateVertex(AdjList *G, int v0);//找到值为v0的数组坐标位置
void CreateDN(AdjList *G);
void BreadthFirstSearch(AdjList *G, int v0);//广度优先搜索
void IsPath(AdjList *G, int vi, int vj);//是否存在路径
void InitQueue(SeqQueue *Q);
void EnterQueue(SeqQueue *Q, int x);
void DeleteQueue(SeqQueue *Q, int *x);
int IsEmpty(SeqQueue *Q);
int main()
{
AdjList g;
int vi, vj;
memset(&g, 0, sizeof(g));
CreateDN(&g);
scanf("%d%d", &vi, &vj);
IsPath(&g, vi, vj);
}
int LocateVertex(AdjList *G, int v0)
{
int i;
for(i = 0; i < G->vernum; i++)
{
if(G->vertex[i].data == v0)
{
break;
}
}
return i;
}
void CreateDN(AdjList *G)
{
int i;
int vi, vj;
int advi, advj;
ArcNode *q;
///1.读入顶点数和边数
scanf("%d%d", &G->vernum, &G->arcnum);
///2.初始化
for(i = 0; i < G->vernum; i++)
{
G->vertex[i].firstarc = NULL;
}
///3.读入顶点
for(i = 0; i < G->vernum; i++)
{
scanf("%d", &G->vertex[i].data);
}
///4.读入边
for(i = 0; i < G->arcnum; i++)
{
scanf("%d%d", &vi, &vj);
//寻找合适的位置插入
advi = LocateVertex(G, vi);
advj = LocateVertex(G, vj);
q = (ArcNode *)malloc(sizeof(ArcNode));
q->adjvex = advj;
q->nextarc = G->vertex[advi].firstarc;
G->vertex[advi].firstarc = q;
}
}
void IsPath(AdjList *G, int vi, int vj)
{
int advi, advj;
advi = LocateVertex(G, vi);
advj = LocateVertex(G, vj);
BreadthFirstSearch(G, advi);
if(visited[advj] == 1)
{
printf("yes");
}
else
{
printf("no");
}
}
void BreadthFirstSearch(AdjList *g, int v0)
{
int v;
ArcNode *p;
SeqQueue Q;
InitQueue(&Q);
///1.v0置访问标志并入队
visited[v0] = 1;
EnterQueue(&Q, v0);
///2.如果队列不空,重复以下操作:
///①队首元素u出队
///②检查u的所有邻接结点w,若w未被访问,则w置访问标志并入队
while(!IsEmpty(&Q))
{
DeleteQueue(&Q, &v);
p = g->vertex[v].firstarc;
while(p != NULL)
{
if(visited[p->adjvex] == 0)
{
visited[p->adjvex] = 1;
EnterQueue(&Q, p->adjvex);
}
p = p->nextarc;
}
}
}
void InitQueue(SeqQueue *Q)
{
Q->front = Q->rear = 0;
}
void EnterQueue(SeqQueue *Q, int x)
{
Q->elem[Q->rear] = x;
Q->rear = (Q->rear + 1) % MAX_VERTEX_NUM;
}
void DeleteQueue(SeqQueue *Q, int *x)
{
*x = Q->elem[Q->front];
Q->front = (Q->front + 1) % MAX_VERTEX_NUM;
}
int IsEmpty(SeqQueue *Q)
{
int flag;
if(Q->front == Q->rear)
{
flag = 1;
}
else
{
flag = 0;
}
return flag;
}