图的广度优先遍历需要借助对列来实现,我们下面来用邻接矩阵和邻接表两种图的结构的遍历.
邻接矩阵的广度优先遍历
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#define MAXSIZE 100
#define MAXPOINT 100 //最大顶点数
#define MAX 1000000 //表示无穷
typedef struct Graph
{
int visited[MAXPOINT]; //下标对应的顶点是否被访问,在图的遍历中会用到.
int point[MAXPOINT]; //顶点数组
int arc[MAXPOINT][MAXPOINT]; //邻接数组
int numPoint, numEdge; //顶点数目, 边的数目
}Graph;
void CreateGraph(Graph *G)
{
int i, j, k, w;
printf("请输入顶点数和边数:\n");
scanf("%d %d", &G->numPoint, &G->numEdge); //输入顶点数目和边数
printf("请输入各个顶点的信息:\n");
for (i = 0; i < G->numPoint; i++)
{
scanf("%d", &G->point[i]); //输入每个顶点的信息.
}
for (i = 0; i < G->numPoint; i++) //邻接矩阵初始化
{
for (j = 0; j < G->numPoint; j++)
{
if (i == j)
G->arc[i][j] = 0;
else
G->arc[i][j] = MAX;
}
}
for (k = 0; k < G->numEdge; k++)
{
printf("请输入边(Vi,Vj)的下标i,下标j和边的权重w:\n");
scanf("%d %d %d", &i, &j, &w);
G->arc[i][j] = w;
G->arc[j][i] = w;
}
}
/*循环队列
最大的尺寸QueueSize , 对列满的条件 (rear+1)%QueueSize==front
计算队列长度 (rear-front+QueueSize0 %QueueSize
*/
typedef struct Queue
{
int data[MAXSIZE];
int rear;
int front;
}Queue;
void initQueue(Queue * pue)
{
memset(pue->data, 0, MAXSIZE * 4);
pue->front = pue->rear = 0;
}
int QueueLength(Queue * pue)
{
assert(pue);
return (pue->rear - pue->front + MAXSIZE) % MAXSIZE;
}
int EnQueue(Queue *pue, int e)
{
assert(pue);
if ((pue->rear + 1) % MAXSIZE == pue->front)
return -1;
pue->data[pue->rear] = e;
pue->rear = (pue->rear + 1) % MAXSIZE;
return 0;
}
int DeQueue(Queue *pue, int *e)
{
assert(pue);
if (pue->front == pue->rear)
return -1;
*e = pue->data[pue->front];
pue->front = (pue->front + 1) % MAXSIZE;
return 0;
}
int QueueEmpty(Queue * pue)
{
if (pue->front == pue->rear)
return 1;
else
return 0;
}
void BFSTraverse(Graph*G)
{
int i, j;
Queue Q;
for (i = 0; i < G->numPoint; i++)
G->visited[i] = 0;
initQueue(&Q);
for (i = 0; i < G->numPoint; i++) //遍历每一个顶点,
{
if (!G->visited[i])
{
G->visited[i] = 1;
printf("%d ", G->point[i]);
EnQueue(&Q, i);
while (!QueueEmpty(&Q))
{
DeQueue(&Q, &i);
for (j = 0; j < G->numPoint; j++)
{
if (G->arc[i][j] > 0 && G->arc[i][j] < MAX && !G->visited[j])
{
G->visited[j] = 1;
printf("%d ", G->point[j]);
EnQueue(&Q, j);
}
}
}
}
}
}
void print(Graph *G)
{
int i, j;
for (i = 0; i < G->numPoint; i++)
{
printf("%-9d", G->point[i]);
}
printf("\n");
for (i = 0; i < G->numPoint; i++)
{
for (j = 0; j < G->numPoint; j++)
{
printf("%-9d", G->arc[i][j]);
}
printf("\n");
}
}
int main()
{
Graph G;
CreateGraph(&G);
BFSTraverse(&G);
system("pause");
return 0;
}
邻接表的广度优先遍历
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define MAXSIZE 100
#define MAXPOINT 100
typedef struct EdgeNdoe //边表结点
{
int index; //邻接点的下标.
int weight; //边的权值.
struct EdgeNode * next; //链域.指向下一个邻接点
}EdgeNdoe;
typedef struct Node //顶点表结点
{
int data; //顶点信息
EdgeNdoe * firstedge; //边表头指针
}Node;
typedef struct Graph
{
Node arr[MAXPOINT];
int numPonit, numEdge; //顶点数目,边的数目.
int visited[MAXPOINT]; //顶点标记数组,图的遍历时有用
}Graph;
//创建邻接表
void CreateGraph(Graph *G)
{
int i, j, k, w;
EdgeNdoe * e;
printf("请输入顶点的和边的数目:\n");
scanf("%d %d", &G->numPonit, &G->numEdge);
printf("请输入各个顶点的信息:\n");
for (i = 0; i < G->numPonit; i++)
{
scanf("%d", &G->arr[i].data);
G->arr[i].firstedge = NULL;
}
for (k = 0; k < G->numEdge; k++)
{
printf("请输入(Vi,Vj)的Vi,Vj的下标和权值W:\n");
scanf("%d %d %d", &i, &j, &w);
e = (EdgeNdoe*)malloc(sizeof(EdgeNdoe));
e->weight = w;
e->index = j;
e->next = G->arr[i].firstedge;
G->arr[i].firstedge = e;
e = (EdgeNdoe*)malloc(sizeof(EdgeNdoe));
e->weight = w;
e->index = i;
e->next = G->arr[j].firstedge;
G->arr[j].firstedge = e;
}
}
typedef struct Queue
{
int data[MAXSIZE];
int rear;
int front;
}Queue;
void initQueue(Queue * pue)
{
memset(pue->data, 0, MAXSIZE * 4);
pue->front = pue->rear = 0;
}
int QueueLength(Queue * pue)
{
assert(pue);
return (pue->rear - pue->front + MAXSIZE) % MAXSIZE;
}
int EnQueue(Queue *pue, int e)
{
assert(pue);
if ((pue->rear + 1) % MAXSIZE == pue->front)
return -1;
pue->data[pue->rear] = e;
pue->rear = (pue->rear + 1) % MAXSIZE;
return 0;
}
int DeQueue(Queue *pue, int *e)
{
assert(pue);
if (pue->front == pue->rear)
return -1;
*e = pue->data[pue->front];
pue->front = (pue->front + 1) % MAXSIZE;
return 0;
}
int QueueEmpty(Queue * pue)
{
if (pue->front == pue->rear)
return 1;
else
return 0;
}
void BFSTraverse(Graph *G)
{
int i;
EdgeNdoe* e;
Queue Q;
initQueue(&Q);
for (i = 0; i < G->numPonit; i++)
G->visited[i] = 0;
for (i = 0; i < G->numPonit; i++)
{
if (!G->visited[i])
{
G->visited[i] = 1;
printf("%d ", G->arr[i].data);
EnQueue(&Q, i);
while (!QueueEmpty(&Q))
{
DeQueue(&Q, &i);
e = G->arr[i].firstedge;
while (e)
{
if (!G->visited[e->index])
{
G->visited[e->index] = 1;
printf("%d ", G->arr[e->index].data);
EnQueue(&Q, e->index);
}
e = e->next;
}
}
}
}
}
int main()
{
Graph G;
CreateGraph(&G);
BFSTraverse(&G);
system("pause");
return 0;
}