一、实验目的
理解和掌握图的概念、邻接矩阵存储结构、邻接表存储结构及图的建立、图的深度优先遍历、图的广度优先遍历的算法等基本理论知识,同时验证图的建立算法、图的深度优先遍历、图的广度优先遍历的算法。
二、实验题目
图的建立和遍历
分别建立一个用邻接矩阵和邻接表存储的图,并对其进行深度优先遍历和广度优先遍历,将遍历序列输出到显示器上。
三、问题分析
邻接矩阵
深度:选择一个顶点一直向下探索直到不能进行回退到上一个
广度:在同一层依次遍历
邻接表
深度:选择一个节点,便将其标志数组对应位置置1,然后访问其邻接结点以此类推
广度:每访问一个节点,便将其标志数组对应位置置1,然后访问其所有未被访问的邻接结点以此类推
四、源程序
#include <stdio.h>
#include <malloc.h>
#define TRUE 1
#define FALSE 0
typedef struct
{
int vertex[20];
int arcs[100][100];
int vexnum, arcnum;
} AdjMatrix;
int CreateMatrix(AdjMatrix* g)
{
int a = 0, b = 0, i = 0, j = 0, m = 0, n = 0;
printf("请输入顶点个数: ");
scanf_s("%d", &a);
g->vexnum = a;
printf("请输入边的个数: ");
scanf_s("%d", &b);
for (i = 1; i <= a; i++)
{
g->vertex[i] = 0;
for (j = 1; j <= a; j++)
{
g->arcs[i][j] = 0;
}
}
for (i = 1; i <= b; i++)
{
printf("请输入第%d条边的弧头和弧尾: ", i);
scanf_s("%d", &m);
scanf_s("%d", &n);
g->arcs[m][n] = 1;
}
return m;
}
void DepthFirstSearch(AdjMatrix* g, int v0)
{
int vj;
printf("%d ", v0);
g->vertex[v0] = TRUE;
for (vj = 1; vj <= g->vexnum; vj++)
{
if (g->vertex[vj] == FALSE && g->arcs[v0][vj] == 1)
{
DepthFirstSearch(g, vj);
}
}
}
void BreadthFirstSearch(AdjMatrix* g, int v0)
{
bool visited[20] = { FALSE };
int queue[20];
int front = 0, rear = 0;
printf("%d ", v0);
visited[v0] = TRUE;
queue[rear++] = v0;
while (front < rear) {
int currentVertex = queue[front++];
for (int i = 1; i <= g->vexnum; i++) {
if (g->arcs[currentVertex][i] == 1 && !visited[i]) {
printf("%d ", i);
visited[i] = TRUE;
queue[rear++] = i;
}
}
}
}
int main()
{
AdjMatrix g;
CreateMatrix(&g);
printf("深度优先搜索结果为:\n");
DepthFirstSearch(&g,1);
printf("广度优先搜索结果为");
BreadthFirstSearch(&g, 1);
return 0;
}
邻接表(广度优先)
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
#define CQ_INIT_SIZE 100
int visited[MAX_VERTEX_NUM];
typedef char VertexType;
typedef int dataType;
typedef struct node
{
VertexType adjvex;
struct node* next;
} EdgeNode;
typedef struct vnode
{
VertexType vex;
EdgeNode* firstedge;
} VertexNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList adjlist;
int vexnum;
int edgenum;
} ALGraph;
typedef struct
{
dataType* data;
int front;
int rear;
int cqCapacity;
} CQueue;
CQueue* initCQueue();
int push(CQueue* Q, dataType x);
int pop(CQueue* Q, dataType* x);
int isEmpty(CQueue* Q);
int isFull(CQueue* Q);
void CreateALG(ALGraph* ALG)
{
VertexType ch;
int i = 0, count = 0;
EdgeNode* temp;
printf("请输入图的顶点:");
while ((ch = getchar()) != '\n')
{
ALG->adjlist[i].vex = ch;
ALG->adjlist[i].firstedge = NULL;
i++;
}
ALG->vexnum = i;
for (i = 0; i < ALG->vexnum; i++)
{
printf("请输入顶点 %c 的邻接顶点:", ALG->adjlist[i].vex);
while ((ch = getchar()) != '\n') {
temp = (EdgeNode*)malloc(sizeof(EdgeNode));
temp->adjvex = ch;
temp->next = ALG->adjlist[i].firstedge;
ALG->adjlist[i].firstedge = temp;
count++;
}
}
ALG->edgenum = count / 2;
}
void TraverseALG(ALGraph ALG)
{
int i;
EdgeNode* index;
if (ALG.vexnum == 0)
{
printf("图为空\n");
return;
}
for (i = 0; i < ALG.vexnum; i++)
{
printf("顶点 %c :", ALG.adjlist[i].vex);
index = ALG.adjlist[i].firstedge;
while (index) {
printf("[ %c ] -> ", index->adjvex);
index = index->next;
}
printf("NULL\n");
}
}
void LocateVex(ALGraph ALG, VertexType vertex, int* index)
{
int i;
for (i = 0; i < ALG.vexnum; i++)
{
if (ALG.adjlist[i].vex == vertex)
{
*index = i;
return;
}
}
printf("节点 %c 定位失败!\n", vertex);
}
void BFSTraverseALG(ALGraph ALG)
{
int i, index;
char ch;
EdgeNode* temp;
CQueue* que = initCQueue();
for (i = 0; i < ALG.vexnum; i++)
{
visited[i] = 0;
}
printf("请输入开始节点:");
scanf_s("%c", &ch);
LocateVex(ALG, ch, &index);
printf("图的广度优先遍历序列:");
if (!visited[index])
{
push(que, index);
visited[index] = 1;
while (!isEmpty(que))
{
pop(que, &index);
printf("%c, ", ALG.adjlist[index].vex);
temp = ALG.adjlist[index].firstedge;
while (temp) {
LocateVex(ALG, temp->adjvex, &index);
if (!visited[index])
{
push(que, index);
visited[index] = 1;
}
temp = temp->next;
}
}
}
}
CQueue* initCQueue()
{
CQueue* Q = (CQueue*)malloc(sizeof(CQueue));
Q->data = (dataType*)malloc(CQ_INIT_SIZE * sizeof(dataType));
Q->front = 0;
Q->rear = 0;
Q->cqCapacity = CQ_INIT_SIZE;
return Q;
}
int isFull(CQueue* Q)
{
return (Q->rear + 1) % Q->cqCapacity == Q->front ? 1 : 0;
}
int isEmpty(CQueue* Q)
{
return Q->front == Q->rear ? 1 : 0;
}
int push(CQueue* Q, dataType x)
{
if (isFull(Q))
{
int increment = Q->cqCapacity / 2;
Q->data = (dataType*)realloc(Q->data,
(Q->cqCapacity + increment) * sizeof(dataType));
if (!Q->data)
{
return 0;
}
Q->cqCapacity += increment;
}
Q->data[Q->rear] = x;
Q->rear = (Q->rear + 1) % Q->cqCapacity;
return 1;
}
int pop(CQueue* Q, dataType* x)
{
if (isEmpty(Q))
{
return 0;
}
else
{
*x = Q->data[Q->front];
Q->front = (Q->front + 1) % Q->cqCapacity;
return 1;
}
}
int main(void)
{
ALGraph g;
CreateALG(&g);
TraverseALG(g);
BFSTraverseALG(g);
return 0;
}
邻接表(深度优先)
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
int visited[MAX_VERTEX_NUM];
typedef char VertexType;
typedef struct node
{
VertexType adjvex;
struct node* next;
} EdgeNode;
typedef struct vnode
{
VertexType vex;
EdgeNode* firstedge;
} VertexNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList adjlist;
int vexnum;
int edgenum;
} ALGraph;
void CreateALG(ALGraph* ALG)
{
VertexType ch;
int i = 0, count = 0;
EdgeNode* temp;
printf("请输入图的顶点:");
while ((ch = getchar()) != '\n')
{
ALG->adjlist[i].vex = ch;
ALG->adjlist[i].firstedge = NULL;
i++;
}
ALG->vexnum = i;
for (i = 0; i < ALG->vexnum; i++)
{
printf("请输入顶点 %c 的邻接顶点:", ALG->adjlist[i].vex);
while ((ch = getchar()) != '\n')
{
temp = (EdgeNode*)malloc(sizeof(EdgeNode));
temp->adjvex = ch;
temp->next = ALG->adjlist[i].firstedge;
ALG->adjlist[i].firstedge = temp;
count++;
}
}
ALG->edgenum = count / 2;
}
void TraverseALG(ALGraph ALG)
{
int i;
EdgeNode* temp;
if (ALG.vexnum == 0)
{
printf("图为空\n");
return;
}
for (i = 0; i < ALG.vexnum; i++)
{
printf("顶点 %c :", ALG.adjlist[i].vex);
temp = ALG.adjlist[i].firstedge;
while (temp)
{
printf("[ %c ] -> ", temp->adjvex);
temp = temp->next;
}
printf("NULL\n");
}
}
void LocateVex(ALGraph ALG, VertexType vertex, int* index)
{
int i;
for (i = 0; i < ALG.vexnum; i++)
{
if (ALG.adjlist[i].vex == vertex)
{
*index = i;
return;
}
}
}
void DFSALG(ALGraph ALG, int i)
{
EdgeNode* temp;
int index;
printf("%c, ", ALG.adjlist[i].vex);
visited[i] = 1;
temp = ALG.adjlist[i].firstedge;
while (temp)
{
LocateVex(ALG, temp->adjvex, &index);
if (!visited[index])
{
DFSALG(ALG, index);
}
temp = temp->next;
}
}
void DFSTraverseALG(ALGraph ALG)
{
int i;
for (i = 0; i < ALG.vexnum; i++)
{
visited[i] = 0;
}
printf("图的深度优先遍历序列:");
for (i = 0; i < ALG.vexnum; i++)
{
if (!visited[i])
{
DFSALG(ALG, i);
}
}
}
int main(void)
{
ALGraph g;
CreateALG(&g);
TraverseALG(g);
DFSTraverseALG(g);
return 0;
}