数据结构之图的遍历
一、图的遍历概念
定义:从已给的连通图中某一顶点出发,沿着一些边访遍图中所有的顶点,且使每一个顶点仅被访问一次,就叫做图的遍历,他说图的基本运算。
遍历的实质:找每个顶点的邻接点的过程。
特点:因为图中是多对多,所有图中有可能存在回路,且图的任一顶点都可能与其他顶点相通,在访问完某个顶点之后可能沿着某些边又回到了曾经访问过的顶点。
避免重复访问思路:设置辅助数组visited[n],用来标记每个被访问过的顶点。
初始状态visited[i]为0,顶点被访问可以修改为1,防止多重被访问
二、图的遍历常用算法
1.深度优先搜索(Depth_First Search——DFS)
理解:选择随机一条路一直走到底,开始回退上一步,判断还有其他的路吗,如果有继续走,直到否则继续回退,直到回退到开始位置,判断是否还有未遍历的,如果没有表示全部已经遍历完毕。
选择的开始不一样,遍历结果也不同。类似于树的先根遍历
(1)邻接矩阵表示的无向图深度遍历实现:
void DFS(AMGraph G,int V) { // 图G为邻接矩阵类型,v为起始顶点
cout << v; visited[v] = true // 访问第v个顶点,修改辅助数组表示已被访问
for(w=0;w<G.vexnum;w++) { // 依次检测邻接矩阵v所在的行
if((G.arcs[v][w] != 0) && (!visited[w]))
DFS(G,w)
// w是v的临界点,如果w未访问,则递归调用DFS
}
}
(2)非连通图的遍历:
通过连通分量 来判断 是否还有还有 生成树中的连通图 未被遍历
(3)算法效率
2.广度优先搜索(Breadth_First Search——BFS)
理解:从某个结点开始划分层级,每一次遍历都遍历完这一层的点,下一次遍历遍历上一次遍历结点所有延伸的结点。
(1)非连通图的广度遍历
一个连接分量遍历完成,才开始遍历下一个连接分量。
(2)广度遍历的实现
void BFS(Graph G,int v) { // 按广度优先遍历
cout << v, visited[v] = true // 访问第v个顶点
InitQueue(Q) // 辅助队列Q初始化,置空
EnQueue(Q,v) // v进队
while(!QueueEmpth(Q)) { // 队列非空
Dequeue(Q,u) // 队头元素出队并置为u
for(w =FirstAdjVex(G,u); w>=0;w = NextAdjVex(G,u,w))
if(!visited[w]) { // w为u的尚访问的邻接顶点
cout << w; visited[w] = true; EnQueue(Q,w) //w进队
}
}
}
(3)算法效率分析
3.广度和深度的比较
空间复杂程度相同,都是O(n)(借用了堆栈或队列)
时间辅助成都只和存储结构(邻接表或邻接矩阵)有关,而与搜索路径无关。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 我与微信审核的“相爱相杀”看个人小程序副业