图的遍历 (深度优先 广度优先)
2016-05-11 16:44
232 查看
——选自《啊哈! 算法》第五章
Traversal
图的邻接矩阵存储法(无向图):
第i行第j列就是顶点i到j是否有边,1表示有边,#表示无边,自己到自己设为0.
无向图:沿主对角线对称。
深度优先遍历:
从5*5的举证来存储:
深度优先寻找从1号城市到5号城市的最短路径:
利用广度优先搜索寻找城市1到城市5的最短路径:
选自《啊哈! 算法》第五章
Traversal
1 / | \ 2 3 ————5 | 4
1.深度优先遍历
1 / | 2 3 ————5 | 4
图的邻接矩阵存储法(无向图):
- | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | 0 | 1 | 1 | # | 1 |
2 | 1 | 0 | # | 1 | # |
3 | 1 | # | 0 | # | 1 |
4 | # | 1 | # | 0 | # |
5 | 1 | # | 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的举证来存储:
- | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | 0 | 2 | # | # | 10 |
2 | # | 0 | 3 | # | 7 |
3 | 4 | # | 0 | 4 | # |
4 | # | # | # | 0 | 5 |
5 | # | # | 3 | # | 0 |
#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; }
选自《啊哈! 算法》第五章
相关文章推荐
- 反演问题中基本概念的理解
- 快速排序算法学习心得(Java实现)
- MyBatis 注解
- js限制上传文件类型和大小
- C语言 文件操作12--文件加密
- hdu 2224 The shortest path
- C#_串口通信_SerialPort_一个最基础的串口程序
- epoll 分析----2
- UIImage两种初始化的区别
- Oracle AWR报告的生成
- 04_Swift2基础之类型安全和类型推测+字面量+类型别名
- android彻底退出问题
- 02_Swift2基础之常量和变量+注释+分号
- Java - HashSet
- iOSDay30之UITableView编辑
- 在 Linux 上安装 Git
- ROS 学习系列 -- iRobot 第二代机座 Roomba 作为Turtlebot使用时无法开关机
- Object-c 开源类库
- 计算机网络之面试常考
- iOS 仿Android Toast效果