图的广度优先查找(BFS: Breadth -First Search) (1)问题分析 BFS的策略是尽可能广泛地搜索图。它首先访问所有和初始顶点邻接的顶点,然后访问距离它两条边的所有未

285 篇文章 1 订阅

 图的广度优先查找(BFS: Breadth -FirstSearch)

(1)问题分析

     BFS的策略是尽可能广泛地搜索图。它首先访问所有和初始顶点邻接的顶点,然后访问距离它两条边的所有未访问的顶点。以此类推,直到所有与初始顶点同在一个连通分量中的顶点都访问过了为止。若仍存在未被访问的顶点,该算法从图的其他连通分量中的任意顶点重新开始。

(2)解题思路

 BFS队列

将遍历的初始顶点作为队列队头顶点,并标记为已访问。在每次迭代时, 该算法找出所有和队头顶点邻接的未访问顶点,将其标记为已访问,并把它们入队,然后从队列中移去队头顶点。


BFS森林

  完全类似DFS森林的定义,只不过在DFS森林中,指向已访问顶点的边称为回边,而在BFS森林中,这种边称为交叉边。


代码实现:

#include <iostream>
#include <cstring>
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)<(b)?(a):(b)
using namespace std;

int map[30][30];
int tof[30];
char arr[100];
int maxn = -1, minn = 30;

// 搜索arr数组从beg到end范围内的顶点
void BFS(int beg, int end)
{
    int i, j, k = end + 1;
    int t;
    int count = 0;

    // 将搜索到的点放入arr数组中
    arr[end] = '\n';
    for (i = beg; i < end; ++i)
    {
        if (arr[i] == '|') continue;
        t = arr[i] - 'a';
        for (j = minn; j <= maxn; ++j)
        {
            if (map[t][j] && tof[j])
            {
                arr[k++] = j + 'a';
                tof[j] = 0;
                count++;
            }
        }
        k++;
    }
    k--;
    arr[k] = '\n';

    // 如果没有点可以继续搜索,则退回上一顶点
    if (!count)
    {
        arr[k] = '\0';
        return ;
    }
    BFS(end + 1, k);
}
int main()
{
    int n, m;
    char a, b;
    int c, d;
    int i, j;

    // 输入
    memset(map, 0, sizeof(map));
    memset(tof, 0, sizeof(tof));
     printf("请输入顶点个数n以及边数m,格式为<n m>:");
    cin >> n >> m;
    printf("请分别输入%d条边所对应的两个顶点,格式为<a b>:\n",m);
    for (i = 0; i < m; ++i)
    {
        cin >> a >> b;
        c = a - 'a';
        d = b - 'a';
        tof[c] = tof[d] = 1;

        // 构建邻接矩阵,求出最小点和最大点
        map[c][d] = map[d][c] = 1;
        maxn = MAX(maxn, c);
        maxn = MAX(maxn, d);
        minn = MIN(minn, c);
        minn = MIN(minn, d);
    }

    // 进行广度优先搜索
    for (i = minn; i <= maxn; ++i)
    {
        if (tof[i])
        {
            // 初始化arr数组
            memset(arr, '|', sizeof(arr));
            arr[0] = i + 'a';
            arr[1] = '\n';
            tof[i] = 0;
            BFS(0, 1);

            // 输出
            printf("广度优先生成树(与每个顶点连接的点在下一行用‘|’隔开)\n");
            for (j = 0; arr[j] != '\0'; ++j)
            {
                if (arr[j] == '\n') printf("\n");
                else printf("%c ", arr[j]);
            }
            printf("\n");
        }
    }
    printf("遍历结束!\n");
}


画如下所示的图:


运行结果:


生成树为:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值