图的遍历---深度优先遍历与广度优先遍历
对下图进行遍历,分别采用深度优先和广度优先
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("广度优先遍历的结果是:\n"); for (i = 1; i<tail; i++) printf(" %d ", que[i]); getchar(); getchar(); return 0; }