为什么深度优先搜索可以判定简单图中是否有环,而宽度优先搜索不行?

2024-02-26 22:59

本文主要是介绍为什么深度优先搜索可以判定简单图中是否有环,而宽度优先搜索不行?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,前言

本文是原创作品,可能有所不足,敬请指正,礼貌交流,感激不尽。

二,前提知识

1,简单图

简单图是指满足以下条件的图:没有连接顶点和其自身的边、不存在平行边。

2,环

这里我们讨论的是简单回路(环),也就是指除了第一个顶点和最后一个顶点相同以外、其他顶点不重复出现的回路。

3,树(单指无向树)的定义是连通无回路的无向图。

约定:

1,以下的“宽搜”二字代表宽度优先搜索,深搜代表深度优先搜索。

2,以下的图均指简单连通图

三,正文

1,首先可以肯定的是,对于无向图而言,宽搜和深搜都能判断是否有环。

简要说明一下,假如一个无向图有环,那么在宽搜的过程中,能搜到已经访问过的结点。如果一个无向图没有环(参考无向树),那么它的宽度优先搜索过程中,是不会访问到已访问过的结点的。

对于深搜,如果一个简单无向图有环,那么深搜的栈保存的结点形成的路径(以下简称深搜结点路径)会有回边(指向栈中结点的边)。但是没有环的话,就不会出现这种情况。

2,对于有向图而言,它们中只有深搜能判断是否有环。

首先对于有向图而言,无论有没有环,宽搜都有可能搜到已访问过的结点。如下图:

当结点B,C都进入了宽搜的队列,那么它们会先后访问D结点,这时就出现了访问已访问过的结点的情况。但是此时该图没有环。 

因此,之前的那个办法不能判断了。

但是深搜依然可以。如果简单有向图中存在环,深搜结点路径依然会出现回边。

四,写在最后

如有错误,敬请指正,礼貌交流,感激不尽

附录,有小伙伴提到了深搜判断无向图是否有环,我写了一下伪代码,逻辑不一定严密,但是大体上应该没错,如有错误,欢迎指正

#include<iostream>
#define N 5
using namespace std;
bool DFS(int node, int tag[],int graph[][5], int parent[])//通过深搜判断无向图是否有环
{//node代表当前结点,tag[i]等于0代表该结点没有在深搜的栈中,tag[i]等于1代表当前结点在深搜的栈中。
//graph数组代表图的邻接矩阵,N代表结点个数,
//parent[i]等于j,代表当前深搜的栈中结点i的前驱是j ,也即访问i之后就立马访问j了 
//该函数返回false代表有环,否则代表无环 if(tag[node] == 1)return false;//遇到回边就返回false else tag[node] = 1;bool res = true;for(int i=0;i<N;i++){if(graph[node][i] > 0 && parent[node] != i)//如果结点node和i之间存在一条边,当前结点的父节点不应该访问 {parent[i] = node;res = DFS( i,  tag, graph, parent);if(res == false)break;//只要有一条回边,就代表整个图有环 parent[i] = -1;tag[i] = 0; } }return res;
} 
int main()
{return 0;
} 

这篇关于为什么深度优先搜索可以判定简单图中是否有环,而宽度优先搜索不行?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750436

相关文章

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言