【数据结构与算法】—— * 图的遍历(一)*

简介: 【数据结构与算法】—— * 图的遍历(一)*

引入

前面我们已经学过了深度和广度搜索。为什么叫深度和广度呢?其实是针对图的遍历而言的,请看下面这个图:

1.png

图是由一些小圆点(称为顶点)连接这些点的直线 (称为边)组成的。

例如上图就是由5个顶点(编号为 1,2,3,4,5)5条边(1-2,1-3,1-4,2-4)组成。

现在我们从1号顶点开始遍历这个图,遍历就是把图的每一个顶点都访问一次。使用深度优先搜索将会得到如下的结果。

2.png

图中每个顶点旁边的数表示这个顶点是第几个被访问到的,我们称之为 —— 时间戳


使用深度优先搜索来遍历这个图的过程

首先从一个未走过的顶点作为起始顶点,比如以1号顶点作为起点。沿1号顶点的边去尝试其他它未走过的顶点,首先发现的是2号顶点还没被走过,于是来到了2号顶点。

再以2号顶点作为出发点继续尝试访问其他未走到过的顶点,这样又来到了4号顶点。

再以4号顶点作为出发点继续尝试访问其他未走过的顶点。但是,此时在4号顶点的周围已经没有其他的顶点了,所以需要返回到2号顶点。返回到2号顶点后,发现沿2号顶点也不能在访问到其他未走到的点了,此时又需要返回到1号顶点。

继续以1号顶点尝试访问其他顶点,我们来到了3号点。以此类推,我们最后来到了5号点。到此,所以的顶点都走过了,遍历结束


深度优先搜索的主要思想是:

首先以一个未被访问的顶点作为起始顶点,沿当前顶点的边走到未被访问过的顶点

当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问过。

显然,深度优先搜索是沿着图的某一条分支遍历直至末端,然后回溯,再沿另一条实现相同的遍历,直到所以的顶点都被访问完为止。


代码实现4.png

上面的二维数组中 第i行第j列就是表示顶点i到顶点j是否有边。

1表示有边,x表示没有边,0表示顶点自己到自己。

我们将这种方法称为 ——  图的邻接矩阵储存法。

细心的朋友可能会发现这张图沿着对角线全部是0,因为上面这张图是 无向图

所谓无向图就是指图的边没有方向。例如边 1 - 5 表示 1号顶点可以到 5号顶点,5号顶点也可以到1号顶点。


接下来就是解决怎么用深度优先搜索来实现遍历了:

voiddfs(intcur)       //cur是当前所在的顶点编号
{
printf("%d", cur);
sum++;            //每访问一个点就sum++
if (sum == n) return;   //所有的顶点都访问过了
for (i = 1; i <= n; i++)  //从1n的顶点依次尝试,看看有哪些顶点与当前顶点cur有边相连
  {
    //判断当前顶点cur到顶点i是否有边,并判断顶点i是否已被访问过
    {
if (e[cur][i] == 1 && book[i] == 0)
      {
book[i] = 1;  //标记顶点i已经访问过
dfs(i);     //从顶点i出发继续遍历
      }
    }
  }
return;
}

在上面的代码中 变量 cur 存储的是当前正在遍历的点,二维数组e存储的就是图的边(邻接矩阵),数组book用来标记哪些顶点已经访问过,变量sum用来记录已经访问多少个顶点,变量你存储的是图的顶点总个数。


完整代码

#include <stdio.h>
intbook[101], sum, n, e[101][101];
voiddfs(intcur)       //cur是当前所在的顶点编号
{
printf("%d", cur);
sum++;            //每访问一个点就sum++
if (sum == n) return;   //所有的顶点都访问过了
for (i = 1; i <= n; i++)  //从1n的顶点依次尝试,看看有哪些顶点与当前顶点cur有边相连
  {
    //判断当前顶点cur到顶点i是否有边,并判断顶点i是否已被访问过
    {
if (e[cur][i] == 1 && book[i] == 0)
      {
book[i] = 1;  //标记顶点i已经访问过
dfs(i);     //从顶点i出发继续遍历
      }
    }
  }
return;
}
intmain()
{
inti, 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;
elsee[i][j] = 99999999;  //我们假设99999999x  //读入顶点之间的边
for (i = 1; i <= n; i++)
  {
scanf("%d %d", &a, &b);
e[a][b] = 1;
e[b][a] = 1;  //因为该图为无向图
  }
  //从1号顶点出发
book[1] = 1;  //标记1号顶点已经访问
dfs(1);     //从1号顶点开始遍历
return0;
}


如果觉得有什么意见或者是需要的话,欢迎在评论区向小玄提出哦!

目录
相关文章
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
323 64
|
10月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
427 3
|
10月前
|
数据采集 存储 算法
【C++数据结构——图】图的遍历(头歌教学实验平台习题) 【合集】
本文介绍了图的遍历算法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。深度优先遍历通过递归方式从起始节点深入探索图,适用于寻找路径、拓扑排序等场景;广度优先遍历则按层次逐层访问节点,适合无权图最短路径和网络爬虫等应用。文中提供了C++代码示例,演示了如何实现这两种遍历方法,并附有测试用例及结果,帮助读者理解和实践图的遍历算法。
493 0
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
314 5
|
算法
树的遍历算法有哪些?
不同的遍历算法适用于不同的应用场景。深度优先搜索常用于搜索、路径查找等问题;广度优先搜索则在图的最短路径、层次相关的问题中较为常用;而二叉搜索树的遍历在数据排序、查找等方面有重要应用。
284 2
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
637 0
|
存储 编译器 C++
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
164 4
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
302 6
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
307 0
【数据结构】遍历二叉树(递归思想)-->赋源码
【数据结构】遍历二叉树(递归思想)-->赋源码
143 4

热门文章

最新文章