图的遍历 (深度优先 广度优先)

——选自《啊哈! 算法》第五章
Traversal

       1
  /    | \
  2    3 ————5
  |
  4

1.深度优先遍历

       1
  /    | 
  2    3 ————5
  |
  4

图的邻接矩阵存储法(无向图):

12345
1011#1
210#1#
31#0#1
4#1#0#
51#1#0

第i行第j列就是顶点i到j是否有边,1表示有边,#表示无边,自己到自己设为0.
无向图:沿主对角线对称。

深度优先遍历:

#include<stdio.h>
int book[101], sum, n, e[101][101];
void dfs(int cur){
    int i;
    printf("%d ",cur);
    sum++;
    if(sum == n) return;
    for(i = 1; i<= n; i++){
        if (e[cur][i] == 1 && book[i] == 0){
            book[i] = 1;

            dfs(i);
        }
    }
    return ;
}

int main(){
    int i,j,m,a,b;
    scanf("%d %d", &n, &m);
    //初始化二维矩阵
    for(i=1;i<=m;i++){
        scanf("%d %d",&a,&b);
        e[a][b] = 1;
        e[b][a] = 1; //无向图
    }
    //从1号城市出发
    book[1] = 1;
    dfs(1);
    getchar();
    return 0;
}

2.使用广度优先遍历:

       1
  /    |    \
  2    3     5
  |
  4

// 首先以一个未被访问过的顶点作为起始顶点,然后将与该顶点相邻且未访问过的顶点放入到队列中

#include <stdio.h>
int main(){
    int book[101] = {0},e[101][101]={0};
    int n,m; //n:顶点数, m:边的条数
    int i,j,a,b;
    int que[101];
    scanf("%d %d",&n,&m);
    for(i = 1;i<=n;i++){
        for(j = 1; j<=n; j++){
            if(i == j) e[i][i] = 0;
            else e[i][j] = 99999999;
        }

    }
    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; // 标记1号顶点已访问
    while(head < tail){
        for(j = 1; j <= n; j++){
            cur = que[head];
            if(e[cur][j] == 1 && book[j] == 0){
                sum++;
                book[j] == 1; 
                que[tail] == j;
                tail++;         
            }
            if(tail > n){
                break;
            }
        }
        head++;
    }

    for(i=1;i<tail;i++){
        printf("%d ",que[i]);
    }
    getchar();
    return 0;

}

3.城市地图——有向图的深度优先遍历

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
第一行的5:5个城市 8:8条公路
2-9行: a b c : 从城市a 到 城市b 的距离为c(不表示从b到a的距离也为c)

从5*5的举证来存储:

12345
102##10
2#03#7
34#04#
4###05
5##3#0

深度优先寻找从1号城市到5号城市的最短路径:

#include<stdio.h>
int min = 99999999, book[101], n, e[101][101];
// cur 是当前所在的城市编号,dis是当前已经走过的路程
void dfs(int cur, int dis){
    int j;
    if(dis > min){
        return ;
    }
    if(cur == n){
        if(dis < min){
             min = dis;
         }
        return ;
    }

    for(j = 1; j<= n; j++){
        if(e[cur][j]!= 99999999 && 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);
    for(i = 1; i<=n; i++){
        for(j = 1;j<=n;j++){
            if(i == j) e[i][j] =0;
            else e[i][j] = 99999999;
        }
    }

    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);

    getchar();
    return 0;
}

4.最少转机——图的广度优先遍历

5 7 1 5  //5个城市 7条航线 1: 起点城市 5:终点城市
1 2
1 3
2 3
2 4
3 4
3 5
4 5

利用广度优先搜索寻找城市1到城市5的最短路径:

#include <stdio.h>
struct node{
    int x; // 城市编号
    int s; // 转机次数
};
int main(){
    struct note que[2501];
    int head, tail;
    int book[2501];
    int e[51][51];
    int cur,i;
    int start=1, end=5;
    //输入数据...


    //BFS
    //初始化队列
    head = 1;
    tail = 1;
    que[tail].x = start;
    que[tail].s = 0;
    book[1] = 1;
    tail++;
    while(head < tail){
        cur = que[head].x;
        for(i = 1; i <= n; i++){
            if(e[cur][i] != 99999999 && book[i] == 0){
                book[i] = 1;
                que[tail].x = i;
                que[tail].s = que[head].s + 1;
                tail++;
            }
            if(que[tail-1].x == end){
                flag = 1;
                break;
            }
        }

        if(flag == 1){
            break;
        }
        head++;
    }

    //输出结果
    printf("%d", que[tail-1].s);
    getchar();
    return 0;

}

选自《啊哈! 算法》第五章

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/power0405hf/article/details/51375951
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞