首页 > 代码库 > 图的遍历---深度优先遍历与广度优先遍历

图的遍历---深度优先遍历与广度优先遍历

对下图进行遍历,分别采用深度优先和广度优先

技术分享

1.深度优先遍历的主要思想:首先从一个未被访问的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;

当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有顶点都被访问。

显然,深度优先遍历是沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有顶点被访问。

/*深度优先搜索算法遍历图的各个顶点*/
#include<stdio.h>
int n, sum, book[101];
int e[101][101];
void dfs(int cur)  //cur当前顶点所在编号
{
    int i;
    printf(" %d ", cur);
    sum++;  //每访问一个顶点,sum就加1
    if (sum == n) 
        return;  //所有的顶点都已经访问过则直接退出

    //从1号顶点到n号顶点依次尝试,看哪些顶点与当前cur顶点有边相连
    for (i = 1; i <= n; i++)
    {
        //判断当前顶点cur到顶点i是否有边,并判断顶点i是否已经访问过
        if (e[cur][i] == 1 && book[i] == 0)
        {
            book[i] = 1; //标记顶点i已经访问过
            dfs(i);//从顶点i再出发进行遍历
        }
    }
    return;
}

int main()
{
    int i, j, m, a, b;
    scanf_s("%d %d", &n, &m);

    //初始化二维矩阵
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
        {
            if (i == j) 
                e[i][j] = 0;
            else
                e[i][j] = 99999999;//这里假设99999999为正无穷
        }

    //读入顶点之间的边
    for (i = 1; i <= m; i++)
    {
        scanf_s("%d %d", &a, &b);
        e[a][b] = 1;
        e[b][a] = 1;//这里是无向图,所以e[b][a] = 1
    }

    //从1号顶点出发
    book[1] = 1;//标记1号顶点已经访问
    printf("深度优先遍历的结果:");
    dfs(1);   //从1号顶点开始遍历

    getchar(); getchar();
    return 0;
}

技术分享

 

2. 广度优先遍历的主要思想:首先以一个未被访问过的顶点作为起始顶点,访问其所有相邻的顶点,然后对每个相邻的顶点,再访问它们相邻的未被访问的顶点,直到所有顶点被访问,遍历结束。

 

/*广度优先搜索算法遍历图的各个顶点*/
#include<stdio.h>

int main()
{
    int i, j, n, m, a, b, cur, e[101][101], book[101] = { 0 };
    int que[10001], head, tail;

    scanf_s("%d %d", &n, &m);

    //初始化二维矩阵
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            if (i == j)
                e[i][j] = 0;
            else 
                e[i][j] = 99999999;//假设99999999为正无穷
    //读入顶点之间的边
    for (i = 1; i <= m; i++)
    {
        scanf_s("%d %d", &a, &b);
        e[a][b] = 1;
        e[b][a] = 1; //这里是无向图,e[b][a] = 1
    }

    //队列初始化
    head = 1;
    tail = 1;

    //从1号顶点出发,将1号顶点加入队列
    que[tail] = 1;
    tail++;
    book[1] = 1; //标记1号顶点已经访问

    //当队列不为空时循环
    while (head < tail&&tail <= n)
    {
        cur = que[head];//当前正在访问的顶点编号
        for (i = 1; i <= n; i++) //从1~n依次尝试
        {
            //判断从顶点cur到顶点i是否有边,并判断顶点i是否已经访问过
            if (e[cur][i] == 1 && book[i] == 0)
            {
                //如果从顶点cur到顶点i有边,并且顶点i没有被访问过,则将顶点i入队
                que[tail] = i;
                tail++;
                book[i] = 1; //标记顶点i已经访问
            }
            if (tail>n)
                break;
        }
        head++;//head++,才能继续往下扩展
    }
    printf("广度优先遍历的结果是:\n");
    for (i = 1; i<tail; i++)
        printf(" %d ", que[i]);

    getchar(); getchar();
    return 0;
            
}

 

技术分享

 

图的遍历---深度优先遍历与广度优先遍历