【C语言 DFS(深度优先搜索)和BFS(广度优先搜索)】

DFS(深度优先搜索)和BFS(广度优先搜索)是两种常用的图或树遍历算法。它们在许多计算机科学问题中都有应用,如路径查找、连通性检测和子图匹配等。以下是对这两种算法的详细解释及示例。

深度优先搜索(DFS)

DFS 是一种遍历或搜索树或图的算法。其主要思想是从起始节点开始,沿着每一个分支尽可能深入地搜索,直到找到目标节点或没有更多节点可访问,然后回溯并继续搜索其他分支。

DFS 算法步骤:
  1. 从起始节点开始,标记该节点已访问。
  2. 访问该节点的每一个邻接节点。
  3. 对每一个未访问的邻接节点,递归调用 DFS。
  4. 如果所有邻接节点都已访问,则回溯到前一个节点。
DFS 示例(以图为例):

假设有以下图:

    A
   / \
  B   C
 / \   \
D   E   F

DFS 遍历顺序可能是:A -> B -> D -> E -> C -> F

示例代码(C 语言):

#include <stdio.h>
#include <stdlib.h>

#define MAX 100 // 定义最大节点数量

int visited[MAX]; // 记录每个节点是否被访问过
int adjMatrix[MAX][MAX]; // 邻接矩阵,表示图的连接情况
int n; // 节点数量

// 深度优先搜索函数
void DFS(int vertex) {
    printf("%d ", vertex); // 打印当前访问的节点
    visited[vertex] = 1; // 标记当前节点为已访问

    // 遍历所有节点,检查是否与当前节点相邻且未被访问
    for (int i = 0; i < n; i++) {
        if (adjMatrix[vertex][i] == 1 && !visited[i]) {
            DFS(i); // 递归调用 DFS,访问相邻节点
        }
    }
}

int main() {
    n = 6; // 设置图中节点的数量
    // 定义图的边(无向图)
    int edges[7][2] = {{0, 1}, {0, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 4}, {4, 5}};
    
    // 初始化邻接矩阵
    for (int i = 0; i < 7; i++) {
        int u = edges[i][0];
        int v = edges[i][1];
        adjMatrix[u][v] = 1;
        adjMatrix[v][u] = 1; // 对于无向图,邻接矩阵是对称的
    }

    // 初始化 visited 数组,设置所有节点为未访问
    for (int i = 0; i < n; i++) {
        visited[i] = 0;
    }

    printf("DFS traversal: ");
    DFS(0); // 从节点 0 开始进行深度优先搜索

    return 0; // 程序结束
}

广度优先搜索(BFS)

BFS 是一种遍历或搜索树或图的算法。其主要思想是从起始节点开始,首先访问所有邻接节点,然后再按层次访问每个邻接节点的邻接节点。

BFS 算法步骤:
  1. 从起始节点开始,标记该节点已访问并将其加入队列。
  2. 从队列中取出一个节点,访问其所有未访问的邻接节点,将它们标记为已访问并加入队列。
  3. 重复步骤 2 直到队列为空。
BFS 示例(以图为例):

假设有以下图:

    A
   / \
  B   C
 / \   \
D   E   F

BFS 遍历顺序是:A -> B -> C -> D -> E -> F

示例代码(C 语言):

#include <stdio.h>
#include <stdlib.h>

#define MAX 100 // 定义最大节点数量

int visited[MAX]; // 记录每个节点是否被访问过
int adjMatrix[MAX][MAX]; // 邻接矩阵,表示图的连接情况
int n; // 节点数量

// 广度优先搜索函数
void BFS(int start) {
    int queue[MAX], front = 0, rear = 0; // 定义队列及其前后指针
    printf("%d ", start); // 打印起始节点
    visited[start] = 1; // 标记起始节点为已访问
    queue[rear++] = start; // 将起始节点加入队列

    // 当队列不为空时,循环进行广度优先搜索
    while (front != rear) {
        int vertex = queue[front++]; // 从队列中取出一个节点
        for (int i = 0; i < n; i++) {
            // 检查是否与当前节点相邻且未被访问
            if (adjMatrix[vertex][i] == 1 && !visited[i]) {
                printf("%d ", i); // 打印访问的节点
                visited[i] = 1; // 标记该节点为已访问
                queue[rear++] = i; // 将该节点加入队列
            }
        }
    }
}

int main() {
    n = 6; // 设置图中节点的数量
    // 定义图的边(无向图)
    int edges[7][2] = {{0, 1}, {0, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 4}, {4, 5}};
    
    // 初始化邻接矩阵
    for (int i = 0; i < 7; i++) {
        int u = edges[i][0];
        int v = edges[i][1];
        adjMatrix[u][v] = 1;
        adjMatrix[v][u] = 1; // 对于无向图,邻接矩阵是对称的
    }

    // 初始化 visited 数组,设置所有节点为未访问
    for (int i = 0; i < n; i++) {
        visited[i] = 0;
    }

    printf("BFS traversal: ");
    BFS(0); // 从节点 0 开始进行广度优先搜索

    return 0; // 程序结束
}

对比 DFS 和 BFS

  • 搜索策略

    • DFS:沿着树或图的每一个分支尽可能深地搜索。
    • BFS:按层次逐层搜索,每层节点都被访问后再访问下一层。
  • 使用数据结构

    • DFS:通常使用栈(递归调用栈)。
    • BFS:使用队列。
  • 适用场景

    • DFS:适用于需要搜索整个路径或所有可能情况的问题,如迷宫求解、拓扑排序等。
    • BFS:适用于搜索最短路径或层次结构的问题,如最短路径求解、广度优先遍历等。
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值