广度优先思想
广度优先(breadth first search): 先被访问的顶点, 其邻接点也先被访问, 借助visited[]数组来记录顶点是否已经被访问
邻接矩阵广度优先
图:
对应邻接矩阵:
初始化数组visit:
visit[0] = 0; visited[1] = 0; ...; visit[4] = 0;
顶点入队列流程
- 顶点a入队列
visited[0] = 1;(表示a这个顶点已经被访问了)
- 顶点a出队列, 通过邻接矩阵找到a的邻接点: b, c, e, 入队列
visited[1] = 1;(表示b这个顶点已经被访问了)
visited[2] = 1;(表示c这个顶点已经被访问了)
visited[4] = 1;(表示e这个顶点已经被访问了)
- 顶点b出队列, 通过邻接矩阵找到b的邻接点且未被访问过: 不存在
- 顶点c出队列, 通过邻接矩阵找到c的邻接点且未被访问过: d 入队列
visited[3] = 1;(表示d这个顶点已经被访问了)
- 顶点e出队列, 通过邻接矩阵找到e的邻接点且未被访问过: 不存在
- 顶点d出队列, 通过邻接矩阵找到d的邻接点且未被访问过: 不存在
整体流程
邻接矩阵广度优先步骤
- 创建数组: 用于表示顶点是否被访问过,并将该数组清零;
- 创建队列: 用于存放顶点的下标(不是存放顶点信息!因为下标更易操作);
- 从起始点出发, 访问并标记, 并将该点入队列;
- 顶点出队列后, 依次访问该顶点未被访问过的邻接点, 并标记, 入队列
- 结束遍历的条件: 队列为空, 结束遍历.
代码实现(c语言)
void BFS_AMG(struct AMG_Graph* graph)
{
int u;
int i;
int visited[MAX] = { 0 };
printf("%c ", graph->Vex[0]); // 访问
visited[0] = 1; // 标记
enqueue(0); // 入队列
while (!is_empty()) // 广度优先遍历结束的条件
{
u = dequeue(); // 出队列
for (i = 0; i<graph->vex_num; ++i)
{
if ((graph->Edge[u][i] == 1) && (visited[i] == 0)) // 是否访问的条件
{
printf("%c ", graph->Vex[i]); // 访问
visited[i] = 1; // 标记
enqueue(i); // 入队列
}
}
}
printf("\n");
}
完整版代码(c语言)
- 队列头文件 - queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <stdio.h>
#define SIZE 512
void enqueue(int n);
int dequeue(void);
int is_empty(void);
int is_full(void);
extern int queue[SIZE];
#endif
- 有向图邻接矩阵头文件 - directed_graph.h
#ifndef __DIRECTED_GRAPH_H__
#define __DIRECTED_GRAPH_H__
#define MAX 100
typedef struct connection {
char tail;
char head;
}connection;
typedef struct d_graph {
int vex_num, edge_num;
char Vex[MAX];
connection con[MAX];
}d_graph;
struct AMG_Graph* Create_AMG_Graph(d_graph* d_graph_data);
void Show_AMG_Graph(struct AMG_Graph* graph);
int search_vex(struct AMG_Graph* graph, char c);
void BFS_AMG(struct AMG_Graph* graph);
#endif
- 队列文件 - queue.c
#include "queue.h"
int queue[SIZE];
int head = 0, tail = 0;
void enqueue(int n)
{
queue[tail] = n;
tail = (tail + 1) % SIZE;
}
int dequeue(void)
{
int n;
n = queue[head];
head = (head + 1) % SIZE;
return n;
}
int is_empty(void)
{
return head == tail;
}
int is_full(void)
{
return (tail + 1) % SIZE == head;
}
- 有向图邻接矩阵文件 - directed_graph.c
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
#include "directed_graph.h"
struct AMG_Graph
{
int vex_num, edge_num;
char Vex[MAX];
int Edge[MAX][MAX];
};
struct AMG_Graph* Create_AMG_Graph(d_graph* d_graph_data)
{
int i, j, a;
char u, v;
struct AMG_Graph* graph;
graph = (struct AMG_Graph*)malloc(sizeof(struct AMG_Graph));
graph->vex_num = d_graph_data->vex_num;
graph->edge_num = d_graph_data->edge_num;
for (i = 0; i < graph->vex_num; ++i)
graph->Vex[i] = d_graph_data->Vex[i];
for (i = 0; i < graph->vex_num; i++)
{
for (j = 0; j < graph->vex_num; j++)
graph->Edge[i][j] = 0;
}
for(a=0; a<graph->edge_num; ++a)
{
u = d_graph_data->con[a].tail;
v = d_graph_data->con[a].head;
i = search_vex(graph, u);
j = search_vex(graph, v);
if (i != -1 && j != -1)
graph->Edge[i][j] = 1;
else
{
printf("You have entered wrong vex, please enter again.\n");
return NULL;
}
}
return graph;
}
void Show_AMG_Graph(struct AMG_Graph* graph)
{
int i, j;
printf("Show the vex: \n");
for (i = 0; i < graph->vex_num; i++)
printf("%c ", graph->Vex[i]);
printf("\n");
printf("Show the adjacency matrices:\n");
for (i = 0; i < graph->vex_num; i++)
{
for (j = 0; j < graph->vex_num; j++)
printf("%d\t", graph->Edge[i][j]);
printf("\n");
}
}
int search_vex(struct AMG_Graph* graph, char c)
{
int i;
for (i = 0; i < graph->vex_num; i++)
{
if (c == graph->Vex[i])
return i;
}
return -1;
}
void BFS_AMG(struct AMG_Graph* graph)
{
int u;
int i;
int visited[MAX] = { 0 };
printf("%c ", graph->Vex[0]); // 访问
visited[0] = 1; // 标记
enqueue(0); // 入队列
while (!is_empty())
{
u = dequeue(); // 出队列
for (i = 0; i<graph->vex_num; ++i)
{
if ((graph->Edge[u][i] == 1) && (visited[i] == 0))
{
visited[i] = 1;
enqueue(i);
printf("%c ", graph->Vex[i]);
}
}
}
printf("\n");
}
- 测试文件 - main.c
#include "directed_graph.h"
#include <stdlib.h>
d_graph* setData();
int main(void)
{
d_graph* d_graph_data = setData();
struct AMG_Graph* d_graph = Create_AMG_Graph(d_graph_data);
Show_AMG_Graph(d_graph);
printf("Traverse the graph through BFS:\n");
BFS_AMG(d_graph);
return 0;
}
d_graph* setData()
{
d_graph* data = (d_graph*)malloc(sizeof(d_graph));
data->vex_num = 5;
data->edge_num = 7;
data->Vex[0] = 'a';
data->Vex[1] = 'b';
data->Vex[2] = 'c';
data->Vex[3] = 'd';
data->Vex[4] = 'e';
data->con[0].tail = 'a';
data->con[0].head = 'b';
data->con[1].tail = 'a';
data->con[1].head = 'c';
data->con[2].tail = 'a';
data->con[2].head = 'e';
data->con[3].tail = 'b';
data->con[3].head = 'c';
data->con[4].tail = 'c';
data->con[4].head = 'd';
data->con[5].tail = 'c';
data->con[5].head = 'e';
data->con[6].tail = 'd';
data->con[6].head = 'e';
return data;
}
运行结果如下