深度优先搜索(DFS)
DFS 是一种用于遍历图的算法。dfs() 函数通过递归访问每个顶点,并打印访问的顶点。它使用一个数组 visited 来标记已经访问过的顶点,避免重复访问。
-
dfs()函数的参数包括图、起始顶点、目标顶点和访问数组。 -
如果当前顶点是目标顶点,函数返回成功。
-
如果当前顶点没有连接到目标顶点,则继续递归地访问它的邻接节点。
#include <stdio.h>
#include <stdlib.h>
#define MaxVertex 6 // 定义图中顶点的最大数量
typedef char E; // 顶点数据类型为字符类型
// 头节点结构,用于存储每个顶点的元素和指向下一个节点的指针
struct HeadNode {
E element; // 存储顶点的值
struct Node* next; // 指向下一个节点的指针
};
// 节点结构,每个节点表示图中的一条边
typedef struct Node {
int nextVertex; // 指向的下一个顶点的索引
struct Node* next; // 指向下一个节点的指针,用于表示多条边
} *Node;
// 图的邻接表结构,包含顶点数量、边数量和顶点数组
typedef struct AdjacencyGraph {
int vertexCount; // 图中的顶点数量
int edgeCount; // 图中的边数量
struct HeadNode vertex[MaxVertex]; // 存储每个顶点的头节点
} *Graph;
// 创建一个新的图并初始化
Graph create() {
Graph graph = malloc(sizeof(struct AdjacencyGraph)); // 为图分配内存
graph->vertexCount = graph->edgeCount = 0; // 初始化顶点和边的数量
return graph;
}
// 向图中添加一个新顶点
void addVertex(Graph graph, E e) {
graph->vertex[graph->vertexCount].element = e; // 将元素赋值给当前顶点
graph->vertex[graph->vertexCount].next = NULL; // 初始化该顶点的next指针为空
graph->vertexCount++; // 增加顶点计数
}
// 向图中添加一条边
void addEdge(Graph graph, int a, int b) {
Node node = graph->vertex[a].next; // 获取顶点a的下一个节点
Node newnode = malloc(sizeof(struct Node)); // 创建一个新的节点
newnode->next = NULL;
newnode->nextVertex = b; // 新节点指向顶点b
if (!node) { // 如果顶点a没有下一个节点
graph->vertex[a].next = newnode; // 直接将新节点连接到a后面
} else { // 否则需要遍历链表,避免重复添加
do {
if (node->nextVertex == b) return; // 如果已存在边a -> b,直接返回
if (node->next) node = node->next; // 继续遍历
else break;
} while (1);
node->next = newnode; // 将新节点插入到链表的末尾
}
graph->edgeCount++; // 增加边的计数
}
// 打印图的邻接表表示
void printGraph(Graph graph) {
for (int i = 0; i < graph->vertexCount; i++) {
printf("%d | %c", i, graph->vertex[i].element); // 打印顶点编号和顶点值
Node node = graph->vertex[i].next; // 获取当前顶点的邻接节点
while (node) {
printf(" -> %d", node->nextVertex); // 打印邻接的顶点编号
node = node->next; // 遍历下一个邻接节点
}
printf("\n");
}
}
// 深度优先搜索(DFS)算法
_Bool dfs(Graph graph, int startVertex, int targetVertex, int *visited) {
printf("%c -> ", graph->vertex[startVertex].element); // 打印当前顶点
visited[startVertex] = 1; // 标记当前顶点为已访问
if (startVertex == targetVertex) return 1; // 如果找到目标顶点,返回成功
Node node = graph->vertex[startVertex].next; // 获取当前顶点的邻接节点
while (node) {
if (!visited[node->nextVertex]) // 如果邻接顶点没有被访问
if (dfs(graph, node->nextVertex, targetVertex, visited)) // 递归调用DFS
return 1; // 如果成功找到目标顶点,返回成功
node = node->next; // 继续遍历下一个邻接节点
}
return 0; // 如果没有找到目标顶点,返回失败
}
int main() {
Graph graph = create(); // 创建一个新图
for (int c = 'A'; c <= 'F'; ++c)
addVertex(graph, (char)c); // 添加顶点A到F
// 添加边(图的结构是有向图)
addEdge(graph, 0, 1); // A -> B
addEdge(graph, 1, 2); // B -> C
addEdge(graph, 1, 3); // B -> D
addEdge(graph, 1, 4); // B -> E
addEdge(graph, 4, 5); // E -> F
// 打印图的邻接表
// printGraph(graph);
int arr[graph->vertexCount]; // 创建一个访问标记数组
for (int i = 0; i < graph->vertexCount; i++)
arr[i] = 0; // 初始化为未访问
// 从A(0)到F(5)进行DFS搜索
printf("\n%d", dfs(graph, 0, 5, arr)); // 搜索是否能从A到F
}
545

被折叠的 条评论
为什么被折叠?



