一个大一小白眼中的深度优先于广度优先(一)

      大家好,这里是一个小白的第一篇博客。好了话不多说,进入正题!!!

1,深e度优'先,这里先对其进行遍历,一定要往下看啊,下面有重点

#include <stdio.h>
int book[101],sum = 0,n,e[101][101];
void dfs(int cur)
{
    int i;
    printf("%d",cur);
    sum++;
    if(sum == n)
    {
        return;//这个return是满足条件时,结束这个程序
     } 
    for(i = 1;i <= n;i++)
    {
        if(e[cur][i] == 1 && book[i] == 0)//cur表示当前所在点,e[cur][i]表示当前点到i点是否有边
        {
            book[i] = 1;
            dfs(i);(1)
        }
    }
    return;//返回上一顶点,继续检测上一个点是否有其他相邻的点 ,因为这里是无向图,所以不需要在(1)后面加上book[i] = 0;
}

int main ()
{
    int i,j,m,a,b;
    scanf("%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] = 99;
    //读入顶点之间的边 
    for(i = 1;i <= m;i++)
    {
        scanf("%d %d",&a,&b);
        e[a][b] = 1;
        e[b][a] = 1;//该图是无向图 ,如果是有向图,即确定了方向,只需用这两个中的第一个
    }
    book[1] = 1;
    dfs(1);//即从1点开始遍历
    return 0;
}

程序输入:5 5

1 2

1 3

1 5

2 4

3 5

将会得到:1 2 4 3 5;

广度优先,无向图遍历

#include <stdio.h>
int main ()
{
    int i,j,n,m,a,b,cur,book[101] = {0},e[101][101];
    int que[10001],head,tail;
    scanf("%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] = 999999;
    for(i = 1;i <= m;i++)
    {
        scanf("%d %d",&a,&b);
        e[a][b] = 1;//对无向图需要这么做, 
        e[b][a] = 1;
    }
    head = 1;
    tail = 1;
    que[tail] = 1;//起始点为1
    tail++;
    book[1] = 1;
    while(head < tail)
    {//当队列不为空
        cur = que[head];
        for(i = 1;i <= n;i++)
        {
            if(e[cur][i] == 1&&book[i] == 0)
            {
                que[tail] = i;
                tail++;
                book[i] = 1;
            }
            if(tail > n)//退出循环的条件 
            {
                break;
            }
        }
        head++;//从上一轮第一次扩展的点处继续扩展 
    }
    for(i = 1;i <= n;i++)
        printf("%d  ",que[i]);
    return 0;
 } 

这里输入和上面一样,但是输出结果1 2 3 5 4;

这是为什么呢?

这正是我要说的,深度优先是确定好一个方向,一直向前走,知道无路可走,则返回上一级,一直到某一个地方有了其他的选择

而广度优先是从起点开始,一层一层向外扩展,即先把与起点相邻且满足条件的店扩展并放进队列之中,而运用队列是为了将结果储存起来,而上面的队列之所以是这种形式,完全是题目要求只需要输出遍历顺序,不需要其他变量。

上面的例子只是最基本的,而下面的例子则不是对数据简单的排序,而加入了一些要求,即需要通过编程解决一些实际问题,

就如我们使用的高德地图,在你输入目的地之后能够为你生成一条最优路线,其中你还可以选择少换乘或是时间更多,诸如此类条件,,,,,,个人觉得都和下面的算法有关

深度优先

#include <stdio.h>
int min = 999999,book[101],n,e[101][101];

void dfs(int cur,int dis)
{
    int j;
    if(dis>min) return;//目的是确保输出的是最短的路程
    if(cur == n)//
    {
        if(dis < min) min = dis;//dis即distant的缩写,代表路程
        return;
    }
    for(j = 1;j <= n;j++)
    {
        if(e[cur][j] != 999999&&book[j] == 0)
        {
            book[j] = 1;
            dfs(j,dis+e[cur][j]);
            book[j] = 0;
        }
    }
    return;
}

int main ()
{
    int i,j,m,a,b,c;
    scanf("%d %d",&n,&m);//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] = 999999;
    for(i = 1;i <= m;i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        e[a][b] = c;
    }
    book[1] = 1;
    dfs(1,0);//起点为1,起始路程为0
    printf("%d",min);
    return 0;
}

输入:5 8

1 2 2

1 5 10

2 3 3

2 5 7

3 1 4

3 4 4

4 5 5

5 3 3输出:9

#include <stdio.h>
struct note
{
    int x;//城市编号 
    int s;//转机次数 
};
 
int main ()
{
    struct note que[2501];
    int e[51][51] = {0},book[51] = {0};
    int head,tail;
    int i,j,n,m,a,b,cur,start,end,flag = 0;
    scanf("%d %d %d %d",&n,&m,&start,&end);
    for(i = 1;i <= n;i++)
        for(j = 1;j <= n;j++)
            if(i == j) e[i][j] = 0;
            else e[i][j] = 999999;
    for(i = 1;i <= m;i++)
    {
        scanf("%d %d",&a,&b);//补充一下这里2和4之间有连线,画图画掉了
        e[a][b] = 1;//对无向图需要这么做, 
        e[b][a] = 1;
    }
    head = 1;
    tail = 1;
    que[tail].x = start;
    que[tail].s = 0;
    tail++;
    book[1] = start;
    
    while(head < tail)
    {
        cur = que[head].x;
        for(j = 1;j <= n;j++)
        {
            if(e[cur][j] != 999999&&book[j] == 0)
            {
                que[tail].x = j;
                que[tail].s = que[head].s+1;//转机次数加一
                tail++;
                book[j] = 1; 
            }
            if(que[tail].x == end)
            {
                flag = 1;
                break;
            }
        }
        if(flag == 1)
            break;
        head++;
     }
     printf("%d ",que[tail-1].s);//因为tail指向为节点的下一个节点,所以要减去1
    return 0;
 } 

输入:5 7 1 5

1 2

1 3

2 3

2 4

3 4

3 5

4 5输出

:2

再说一遍,队列只是为了储存你想要得到的东西。这俩个例子实际上都可以换成两种方法中的另一种方法来做,这里广度优先搜索更加适合于两点间权值相同的情况。

希望多多支持!!!

猜你喜欢

转载自blog.csdn.net/weixin_45773632/article/details/105182110
今日推荐