zoukankan      html  css  js  c++  java
  • 啊哈,算法自学记——8th

    图:
    简单地说,图就是由一-些小圆点(称为顶点)和连接这些小圆点的直线(称为边)组成的。例如上图是由五个顶点(编号为1、2、3、4、5)和5条边(1-2、1-3、1-5、2-4、3-5)组成。
    在这里插入图片描述

    图中每个顶点右上方的数就表示这个顶点是第几个被访问到的,我们还为这个数起了很好听的名字一时间戳

    在这里插入图片描述

    深度优先遍历的主要思想就是:
    首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点:当没有未访问过的顶点时,则回到上-一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问过。显然,深度优先遍历是沿着图的某一条 分支遍历直到末端,然后回溯,再沿着另- -条进行同样的遍历,直到所有的顶点都被访问过为止。
    他访问的顺序依次是1-2-4-3-5

    广度优先遍历的主要思想就是:
    首先以一个未被访问过的顶点作为起始顶点,访问其所有相邻的顶点,然后对每个相邻的顶点,再访问它们相邻的未被访问过的顶点,直到所有顶点都被访问过,遍历结束。(像剥洋葱一样,一层一层遍历)
    它访问的顺序依次是:1-2-3-5-4

    图的存储:

    在这里插入图片描述
    上图二维数组中第i行第j列表示的就是顶点i到顶点j是否有边。1表示有边,∞表示没有边,这里我们将自己到自己(即i等于j)设为0。我们将这种存储图的方法称为图的邻接矩阵存储法

    深度优先搜索:

    #include <stdio.h>
    
    int book[101],sum,n,e[101][101];
    
    void dfs(int cur)
    {
        printf("%d ",cur);
        sum++;
        if(sum==n)return;
        for (int i = 1; i <= n; i++)
        {
            if (e[cur][i]==1 && book[i]==0)
            {
                book[i]=1;
                dfs(i);
            }
        }
        return;
    }
    
    int main(int argc, char const *argv[])
    {
        int i,j,m,a,b;
    
        printf("Input the size of the map:
    ");
        scanf("%d %d",&n,&m);
    
        for (int i = 1; i <= n; i++)//初始化数组
        {
            for (int j = 1; j <= m; j++)
            {
                if(i==j)
                    e[i][j]=0;//自己到自己的设为0
                else
                {
                    e[i][j]=999999;//没有边的设为∞,用999999来代替
                }
                
            }
            
        }
    
        //读定点之间的边
        for (int i = 1; i <= m; i++)    
        {
            printf("Input a line:
    ");
            scanf("%d %d",&a,&b);
            e[a][b]=1;
            e[b][a]=1;//双向图所以e[b][a]=1
        }
        
        book[1]=1;//从一号位出发,标记一号位已经访问过
        dfs(1);
    
        return 0;
    }
    
    

    运行结果:
    在这里插入图片描述

    广度优先搜索:

    #include <stdio.h>
    
    int main(int argc, char const *argv[])
    {
        int cur,a,b,m,n,e[101][101],book[101]={0};
        int que[10001],head,tail;
    
        printf("Input the size of the map:
    ");
        scanf("%d %d",&n,&m);
    
        for (int i = 1; i <= n; i++)//初始化数组
        {
            for (int j = 1; j <= m; j++)
            {
                if(i==j)
                    e[i][j]=0;//自己到自己的设为0
                else
                {
                    e[i][j]=999999;//没有边的设为∞,用999999来代替
                }
                
            }
            
        }
    
        //读定点之间的边
        for (int i = 1; i <= m; i++)    
        {
            printf("Input a line:
    ");
            scanf("%d %d",&a,&b);
            e[a][b]=1;
            e[b][a]=1;//双向图所以e[b][a]=1
        }
    
        //队列初始化
        head=1;
        tail=1;
    
        //从一号位出发
        que[tail]=1;//入队
        tail++;
        book[1]=1;//标记一号位已经遍历过
    
        while (head<tail)//队列不为空的时候循环 
        {
            cur=que[head];//当前正在访问的定点编号
            for (int i = 1; i <= n;  i++)//从1~n依次尝试
            {
                if (e[cur][i]==1 && book[i]==0)//如果有边并且没有遍历过
                {
                    que[tail]=i;//加入队列
                    tail++;
                    book[i]=1;//标记
                }
                
                if(tail>n)//说明所有定点都别访问过了
                    break;
            }
            head++;//当一个定点扩展后,head++才能继续向下扩展
        }
        
        printf("Result:
    ");
        for (int i = 1; i < tail; i++)
        {
            printf("%d ",que[i]);
        }
        
        return 0;
    }
    
    

    运行结果:
    在这里插入图片描述

  • 相关阅读:
    1202实验三 进程调度实验
    1111实验二 作业调度模拟实验
    1009实验一 认识DOS
    一起了解操作系统发展史
    0909
    进程调度模拟程序
    试验三同学评论
    实验三 进程调度模拟程序
    作业调度模拟程序
    DOS命令解释程序的编写
  • 原文地址:https://www.cnblogs.com/hhsxy/p/14018426.html
Copyright © 2011-2022 走看看