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


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

    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("广度优先遍历的结果是:
    ");
        for (i = 1; i<tail; i++)
            printf(" %d ", que[i]);
    
        getchar(); getchar();
        return 0;
                
    }

  • 相关阅读:
    在Cortex-M系列上如何准确地做us级延时?
    [嵌入式开发]Linux性能分析——上下文切换
    cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。
    PuTTY配置
    LINUX内核笔记:自旋锁
    Vue的父子组件间通信及借助$emit和$on解除父子级通信的耦合度高的问题
    elementUi中input输入字符光标在输入一个字符后,光标失去焦点
    elementUi中的计数器ele-mumber中的change事件传参及事件调用
    如何使用git拉取代码及提交代码(详细)
    git 拉取远程代码
  • 原文地址:https://www.cnblogs.com/lxt1105/p/6437792.html
Copyright © 2020-2023  润新知