完成图的深度优先遍历算法、广度优先遍历算法。其中,邻接表的创建相当于创建多个单链表。可输入多条边多个节点的字母所构成的图
时间: 2024-03-10 22:46:07 浏览: 17
好的,我可以帮你回答这个问题。以下是图的深度优先遍历算法和广度优先遍历算法的实现,以及邻接表的创建过程。
邻接表的创建:
我们可以使用一个数组来存储图中的所有节点,每个节点对应一个单链表,链表中存储该节点指向的其他节点。具体实现如下:
```
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
// 邻接表节点
typedef struct AdjListNode {
int dest; // 目标节点编号
struct AdjListNode* next; // 指向下一个邻接节点的指针
} AdjListNode;
// 邻接表
typedef struct AdjList {
AdjListNode* head; // 链表头指针
} AdjList;
// 图结构体
typedef struct Graph {
int V; // 节点数量
AdjList* array; // 邻接表数组
} Graph;
// 创建邻接表节点
AdjListNode* createAdjListNode(int dest) {
AdjListNode* newNode = (AdjListNode*)malloc(sizeof(AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// 创建图
Graph* createGraph(int V) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->V = V;
graph->array = (AdjList*)malloc(V * sizeof(AdjList));
for (int i = 0; i < V; i++) {
graph->array[i].head = NULL;
}
return graph;
}
// 添加边
void addEdge(Graph* graph, int src, int dest) {
AdjListNode* newNode = createAdjListNode(dest);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
}
// 打印图
void printGraph(Graph* graph) {
for (int i = 0; i < graph->V; i++) {
AdjListNode* cur = graph->array[i].head;
printf("节点 %d 的邻接节点为:", i);
while (cur) {
printf("%d ", cur->dest);
cur = cur->next;
}
printf("\n");
}
}
```
以上代码中,我们使用了 `Graph` 结构体来表示图,其中 `V` 表示节点数量,`array` 是一个指向邻接表数组的指针。邻接表数组中的每个元素是一个 `AdjList` 结构体,表示一个单链表,链表的头指针存储在 `head` 中。`AdjListNode` 结构体表示邻接表中的节点,其中 `dest` 表示目标节点编号,`next` 表示指向下一个邻接节点的指针。`createAdjListNode` 函数用于创建邻接表节点,`createGraph` 函数用于创建图,`addEdge` 函数用于添加边,`printGraph` 函数用于打印图。
接下来是深度优先遍历算法和广度优先遍历算法的实现。
深度优先遍历算法:
```
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
// 邻接表节点
typedef struct AdjListNode {
int dest; // 目标节点编号
struct AdjListNode* next; // 指向下一个邻接节点的指针
} AdjListNode;
// 邻接表
typedef struct AdjList {
AdjListNode* head; // 链表头指针
} AdjList;
// 图结构体
typedef struct Graph {
int V; // 节点数量
AdjList* array; // 邻接表数组
} Graph;
// 创建邻接表节点
AdjListNode* createAdjListNode(int dest) {
AdjListNode* newNode = (AdjListNode*)malloc(sizeof(AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// 创建图
Graph* createGraph(int V) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->V = V;
graph->array = (AdjList*)malloc(V * sizeof(AdjList));
for (int i = 0; i < V; i++) {
graph->array[i].head = NULL;
}
return graph;
}
// 添加边
void addEdge(Graph* graph, int src, int dest) {
AdjListNode* newNode = createAdjListNode(dest);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
}
// 深度优先遍历算法
void DFSUtil(Graph* graph, int v, int visited[]) {
visited[v] = 1;
printf("%d ", v);
AdjListNode* cur = graph->array[v].head;
while (cur) {
if (!visited[cur->dest]) {
DFSUtil(graph, cur->dest, visited);
}
cur = cur->next;
}
}
void DFS(Graph* graph, int start) {
int visited[MAX_VERTEX_NUM] = {0};
DFSUtil(graph, start, visited);
}
// 广度优先遍历算法
void BFS(Graph* graph, int start) {
int visited[MAX_VERTEX_NUM] = {0};
int queue[MAX_VERTEX_NUM];
int front = 0, rear = 0;
visited[start] = 1;
queue[rear++] = start;
while (front != rear) {
int v = queue[front++];
printf("%d ", v);
AdjListNode* cur = graph->array[v].head;
while (cur) {
if (!visited[cur->dest]) {
visited[cur->dest] = 1;
queue[rear++] = cur->dest;
}
cur = cur->next;
}
}
}
// 打印图
void printGraph(Graph* graph) {
for (int i = 0; i < graph->V; i++) {
AdjListNode* cur = graph->array[i].head;
printf("节点 %d 的邻接节点为:", i);
while (cur) {
printf("%d ", cur->dest);
cur = cur->next;
}
printf("\n");
}
}
int main() {
Graph* graph = createGraph(7);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
addEdge(graph, 2, 4);
addEdge(graph, 3, 5);
addEdge(graph, 4, 5);
addEdge(graph, 4, 6);
printf("邻接表创建完成,图的信息如下:\n");
printGraph(graph);
printf("深度优先遍历结果:");
DFS(graph, 0);
printf("\n");
printf("广度优先遍历结果:");
BFS(graph, 0);
printf("\n");
return 0;
}
```
以上代码中,我们实现了深度优先遍历算法和广度优先遍历算法。深度优先遍历算法使用了递归的方式,从起点开始,遍历所有未访问的邻接节点。广度优先遍历算法使用了队列,从起点开始,依次访问与起点距离为 $1, 2, 3, \dots$ 的所有节点。在实现过程中,我们使用了一个 `visited` 数组来记录每个节点是否被访问过,使用一个队列来记录待访问的节点。
最后,我们测试一下代码的运行结果。假设我们的图如下所示:
```
0
/ \
1 2
/ \ \
3 4 4
/ \ \
5 5 6
```
则程序输出如下:
```
邻接表创建完成,图的信息如下:
节点 0 的邻接节点为:2 1
节点 1 的邻接节点为:4 3
节点 2 的邻接节点为:4
节点 3 的邻接节点为:5
节点 4 的邻接节点为:6 5
节点 5 的邻接节点为:
节点 6 的邻接节点为:
深度优先遍历结果:0 1 3 4 5 6 2
广度优先遍历结果:0 2 1 4 3 5 6
```