问题描述
使用邻接表存储下图所示无向图,使用广度优先搜索遍历无向图上的各节点
** **
解题思路
1、创建一个邻接表接受无向图信息
2、创建队列接受已经访问过的节点
3、始自图中顶点开始搜索,将首先访问顶点;再依次访问顶点所有未访问到的邻居;再按后者被访问的先后次序,逐个访问它们的邻居;如此不断,直至所有的点均被访问过
程序实现
#include <stdlib.h>
#include <stdio.h>
#define MAXVEX 10
#define TRUE 1
#define FALSE 0
/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Status;
/* 顶点类型应由用户定义 */
typedef char VertexType;
/* 边上的权值类型应由用户定义 */
typedef int EdgeType;
/* 邻接表的数据结构 */
typedef struct EdgeNode {
// 邻接点域,存储该顶点对应的下标
int adjvex;
// 链域,指向下一个邻接点
struct EdgeNode *next;
} EdgeNode;
// 顶点表结点
typedef struct VertexNode {
// 顶点域,存储顶点信息
VertexType data;
// 边表头指针
EdgeNode *firstedge;
} VertexNode, AdjList[MAXVEX];
typedef struct {
AdjList adjList;
// 图中顶点数
int numNodes;
// 图中边数
int numEdges;
} GraphAdjList, *GraphList;
/* 队列的数据结构 */
typedef struct {
int data[MAXVEX];
int front;
int rear;
} Queue;
Status initQueue(Queue *q);
Status emptyQueue(Queue *q);
Status enterQueue(Queue *q, int data);
void createMyGraph(GraphList *plus);
void BFS(GraphList plus);
int main(void) {
int i, j;
GraphList plus;
createMyGraph(&plus);
for (i = 0; i < plus->numNodes; i++) {
printf("%c:\t", plus->adjList[i].data);
EdgeNode *e;
e = plus->adjList[i].firstedge;
while (e != NULL) {
printf("%c\t", plus->adjList[e->adjvex].data);
e = e->next;
}
free(e);
printf("\n");
}
BFS(plus);
}
/**
* 初始化队列
*/
Status initQueue(Queue *q) {
q->front = 0;
q->rear = 0;
return TRUE;
}
/**
* 判断队列是否为空
*/
Status emptyQueue(Queue *q) {
if (q->front == q->rear) {
return TRUE;
} else {
return FALSE;
}
}
/**
* 入队操作
*/
Status enterQueue(Queue *q, int data) {
if ((q->rear + 1) % MAXVEX == q->front) {
return FALSE;
}
q->data[q->rear] = data;
q->rear = (q->rear + 1) % MAXVEX;
return TRUE;
}
/**
* 出队操作
*/
Status deQueue(Queue *q, int *e) {
if (emptyQueue(q)) {
return FALSE;
}
*e = q->data[q->front];
q->front = (q->front + 1) % MAXVEX;
return TRUE;
}
/**
* 创建无向图
*/
void createMyGraph(GraphList *plus) {
int i, j, k, w;
EdgeNode *e;
printf("请输入顶点数和边数:\n");
scanf("%d,%d", &i, &j);
*plus = (GraphList)malloc(sizeof(GraphAdjList));
getchar();
(*plus)->numNodes = i;
(*plus)->numEdges = j;
// 读入顶点数
for (i = 0; i < (*plus)->numNodes; i++) {
// 输入顶点信息
scanf("%c", &(*plus)->adjList[i].data);
// 将边表置为空表
(*plus)->adjList[i].firstedge=NULL;
}
// 读入numEdges条边,建立邻接矩阵
for(k = 0; k < (*plus)->numEdges; k++) {
printf("输入边(vi,vj)上的下标i,下标j:\n");
scanf("%d,%d", &i, &j);
// 向内存申请空间,生成边表结点
e = (EdgeNode *)malloc(sizeof(EdgeNode));
// 邻接序号为j
e->adjvex = j;
// 将e的指针指向当前顶点上指向的结点
e->next = (*plus)->adjList[i].firstedge;
// 将当前顶点的指针指向e
(*plus)->adjList[i].firstedge = e;
// 因为是无向图,所以需对称存储
// 向内存申请空间,生成边表结点
e=(EdgeNode *)malloc(sizeof(EdgeNode));
// 邻接序号为i
e->adjvex=i;
// 将e的指针指向当前顶点上指向的结点
e->next= (*plus)->adjList[j].firstedge;
// 将当前顶点的指针指向e
(*plus)->adjList[j].firstedge=e;
}
}
// 访问标志的数组
int visited[MAXVEX];
void BFS(GraphList plus) {
int i;
EdgeNode *p;
Queue q;
for (i = 0; i < plus->numNodes; i++) {
visited[i] = FALSE;
}
initQueue(&q);
for (i = 0; i < plus->numNodes; i++) {
if (!visited[i]) {
visited[i] = TRUE;
printf("%c ", plus->adjList[i].data);
enterQueue(&q, i);
while (!emptyQueue(&q)) {
deQueue(&q, &i);
// 找到当前顶点的边表链表头指针
p = plus->adjList[i].firstedge;
while (p != NULL) {
if (!visited[p->adjvex]) {
visited[p->adjvex] = TRUE;
printf("%c ", plus->adjList[p->adjvex].data);
enterQueue(&q, p->adjvex);
}
p = p->next;
}
}
}
}
}
运行结果