分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历。
运算分析:
(1)深度优先遍历:
①从图中某个顶点V0出发,首先访问V0。
②找出刚访问过的顶点的第一个未被访问的邻接点,然后访问该顶点。以该顶点为新顶点,重复此步骤,直到刚访问过的顶点没有未被访问的邻接点为止。
③返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点,访问该顶点;然后执行步骤②。
(2)广度优先遍历:
①从图中某个顶点v0出发,首先访问v0。
②依次访问v0的各个未被访问的邻接点。
③分别从这些邻接点(端结点)出发,依次访问它们的各个未被访同的邻接点(新的端结点)。访问时应保证:如果vi和vk为当前端结点,且vi在vk之前被访问,则vi的所有未被访问的邻接点应在vk的所有未被访问的邻接点之前访问。重复③,直到所有端结点均没有未被访问的邻接点为止。
测试数据分析:
一、邻接矩阵表示法
#include <stdio.h>
#include <stdlib.h>
#define MAXVNUM 100 // 最大顶点数
#define INFINITY 65535
int visited[MAXVNUM]={0}; // 记录顶点是否已被访问
typedef char VerData;
typedef struct {
VerData vertex[MAXVNUM]; // 顶点数组
int arc[MAXVNUM][MAXVNUM]; // 邻接矩阵
int vertexnum; // 顶点数量
int arcnum; // 边数量
}AdjMatrix;
typedef struct Node
{
VerData data;
struct Node* next;
}LinkQueueNode;
typedef struct
{
LinkQueueNode* front;
LinkQueueNode* rear;
}LinkQueue;
int InitQueue(LinkQueue* Q)
{
Q->front = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (Q->front!= NULL)
{
Q->rear = Q->front;
Q->front->next = NULL;
return 1;
}
else return 0;
}
int EnterQueue(LinkQueue* Q, VerData x)
{
LinkQueueNode* NewNode;
NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (NewNode != NULL)
{
NewNode->data = x;
NewNode->next = NULL;
Q->rear->next = NewNode;
Q->rear = NewNode;
return 1;
}
else return 0;
}
int DeleteQueue(LinkQueue* Q, VerData* x)
{
LinkQueueNode* p;
if (Q->front->next == NULL)
return 0;
p = Q->front->next;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
*x = p->data;
free(p);
return 1;
}
int locateVex(AdjMatrix* G, VerData u)
{
int j =-1, k;
for (k = 0; k < G->vertexnum; k++)
if (G->vertex[k] == u){
j=k;
break;
}
return (j);
}
int createGraph(AdjMatrix* G)
{
int i,j,k,w; //i,j代表顶点下标,w代表权值
VerData v1,v2; //v1,v2为顶点数据
printf("请输入顶点个数和边的数量!\n");
scanf("%d %d", &G->vertexnum,&G->arcnum);
getchar();
for (i = 0; i < G->vertexnum; i++){
for (j = 0; j < G->vertexnum; j++){
G->arc[i][j] = INFINITY;
}
}
printf("请输入顶点!\n");
for (i = 0; i < G->vertexnum; i++)
scanf(" %c", &G->vertex[i]);//输入顶点数据
getchar();
printf("请输入顶点和权重!\n");
for (k = 0; k < G->arcnum; k++)
{
scanf("%c %c %d",&v1,&v2,&w);
getchar();
i = locateVex(G,v1);
j = locateVex(G,v2);
G->arc[i][j] = w;
G->arc[j][i] = w;
}
printf("\n");
return 1;
}
void showGraph(AdjMatrix *G)
{
printf("邻接矩阵:\n");
for (int i = 0; i < G->vertexnum; i++)
{
for (int j = 0; j < G->vertexnum; j++)
{
if (G->arc[i][j] == INFINITY)
printf("0 ");
else
printf("%d ", G->arc[i][j]);
}
printf("\n");
}
printf("\n");
}
void DFS(AdjMatrix* G, int v) {
visited[v] = 1;
printf("%c ", G->vertex[v]);
for (int i = 0; i < G->vertexnum; i++) {
if (G->arc[v][i] != INFINITY && !visited[i]) {
DFS(G, i);
}
}
}
void DFSTraverse(AdjMatrix* G) {
for (int i = 0; i < G->vertexnum; i++) {
visited[i] = 0;
}
for (int i = 0; i < G->vertexnum; i++) {
if (!visited[i]) {
DFS(G, i);
}
}
}
void BFSTraverse(AdjMatrix* G) {
LinkQueue Q;
InitQueue(&Q);
for (int i = 0; i < G->vertexnum; i++) {
visited[i] = 0;
}
for (int i = 0; i < G->vertexnum; i++) {
if (!visited[i]) {
visited[i] = 1;
printf("%c ", G->vertex[i]);
EnterQueue(&Q, G->vertex[i]);
while (Q.front != Q.rear)
{
VerData u;
DeleteQueue(&Q, &u);
int k = locateVex(G, u);
for (int j = 0; j < G->vertexnum; j++) {
if (G->arc[k][j] != INFINITY && !visited[j]) {
visited[j] = 1;
printf("%c ", G->vertex[j]);
EnterQueue(&Q, G->vertex[j]);
}
}
}
}
}
}
int main() {
AdjMatrix G;
createGraph(&G);
showGraph(&G);
printf("深度优先遍历结果:");
DFSTraverse(&G);
printf("\n");
printf("广度优先遍历结果:");
BFSTraverse(&G);
printf("\n");
return 0;
}
测试结果:
二、邻接表表示法
#include <stdio.h>
#include <stdlib.h>
#define MAXVNUM 100
typedef char VerData;
typedef struct ArcNode {
int adjvex;
struct ArcNode* nextarc;
} ArcNode;
typedef struct VertexNode {
VerData data;
ArcNode* firstarc;
} VertexNode;
typedef struct {
VertexNode vertex[MAXVNUM];
int vertexnum;
int arcnum;
} AdjList;
typedef struct Node {
VerData data;
struct Node* next;
} LinkQueueNode;
typedef struct {
LinkQueueNode* front;
LinkQueueNode* rear;
} LinkQueue;
int visited[MAXVNUM];
void DFS(AdjList* G, int v) {
printf("%c ", G->vertex[v].data);
visited[v] = 1;
ArcNode* p = G->vertex[v].firstarc;
while (p != NULL) {
if (!visited[p->adjvex]) {
DFS(G,p->adjvex);
}
p = p->nextarc;
}
}
void DFSTraverse(AdjList* G) {
int i;
for (i = 0; i < G->vertexnum; i++)
visited[i] = 0;
for (i = 0; i < G->vertexnum; i++)
if (!visited[i])
DFS(G, i);
}
int InitQueue(LinkQueue* Q) {
Q->front = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (Q->front != NULL) {
Q->rear = Q->front;
Q->front->next = NULL;
return 1;
}
else return 0;
}
int EnterQueue(LinkQueue* Q, VerData x) {
LinkQueueNode* NewNode;
NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if (NewNode != NULL) {
NewNode->data = x;
NewNode->next = NULL;
Q->rear->next = NewNode;
Q->rear = NewNode;
return 1;
}
else return 0;
}
int DeleteQueue(LinkQueue* Q, VerData* x) {
LinkQueueNode* p;
if (Q->front == Q->rear)
return 0;
p = Q->front->next;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
*x = p->data;
free(p);
return 1;
}
void BFSTraverse(AdjList* G) {
LinkQueue Q;
InitQueue(&Q);
for (int i = 0; i < G->vertexnum; i++) {
visited[i] = 0;
}
for (int i = 0; i < G->vertexnum; i++) {
if (!visited[i]) {
visited[i] = 1;
printf("%c ", G->vertex[i].data);
EnterQueue(&Q, G->vertex[i].data);
while (Q.front != Q.rear) {
VerData u;
DeleteQueue(&Q, &u);
int k = locateVex(G, u);
ArcNode* p = G->vertex[k].firstarc;
while (p != NULL) {
if (!visited[p->adjvex]) {
visited[p->adjvex] = 1;
printf("%c ", G->vertex[p->adjvex].data);
EnterQueue(&Q, G->vertex[p->adjvex].data);
}
p = p->nextarc;
}
}
}
}
}
int locateVex(AdjList* G, VerData u) {
int i;
for (i = 0; i < G->vertexnum; i++)
if (G->vertex[i].data == u)
return i;
return -1;
}
int createGraph(AdjList* G) {
int i, j, k;
VerData v1=0, v2=0,e;
printf("请输入顶点个数和边的数量!\n");
scanf_s("%d %d", &G->vertexnum, &G->arcnum);
e=getchar();
printf("请输入顶点!\n");
for (i = 0; i < G->vertexnum; i++) {
scanf_s(" %c", &G->vertex[i].data,1);
G->vertex[i].firstarc = NULL;
}
e=getchar();
printf("请输入各边的顶点!\n");
for (k = 0; k < G->arcnum; k++) {
scanf_s("%c %c",&v1,1,&v2,1);
e=getchar();
i = locateVex(G, v1);
j = locateVex(G, v2);
ArcNode* p1;
p1= (ArcNode*)malloc(sizeof(ArcNode));
if (p1 == NULL) return;
p1->adjvex = j;
p1->nextarc = G->vertex[i].firstarc;
G->vertex[i].firstarc = p1;
ArcNode* p2;
p2 = (ArcNode*)malloc(sizeof(ArcNode));
if (p2 == NULL) return;
p2->adjvex = i;
p2->nextarc = G->vertex[j].firstarc;
G->vertex[j].firstarc = p2;
}
return 1;
}
void ShowList(AdjList G) {
ArcNode* p;
p = (ArcNode*)malloc(sizeof(ArcNode));
printf("邻接表:\n");
for (int i = 0; i < G.vertexnum; i++)
{
printf(" %c", G.vertex[i].data);
for (p = G.vertex[i].firstarc; p != NULL; p = p->nextarc)
printf("->%d", p->adjvex);
printf("\n");
}
}
int main() {
AdjList G;
createGraph(&G);
ShowList(G);
printf("\n深度优先遍历结果:");
DFSTraverse(&G);
printf("\n广度优先遍历结果:");
BFSTraverse(&G);
printf("\n");
return 0;
}
测试结果: