图、深度优先(DFS)、广度优先(BFS)

基本介绍

表示方式

图的创建

from typing import Listclass Graph:vertex_list: List[str] = []  # 存储顶点的数组edges: List[list] = []  # 存储图中各条边的邻接矩阵num_edges: int = 0  # 边的数总数def __init__(self, n: int):"""根据传入的顶点个数初始化顶点数组和邻接矩阵n: 图中的顶点个数"""for i in range(n):arr = []for j in range(n):arr.append(0)self.edges.append(arr)def insert_vertex(self, vertex_val: str):"""添加顶点vertex_val: 顶点的值"""self.vertex_list.append(vertex_val)def insert_edge(self, v1: int, v2: int, weight: int = 0):"""添加边v1: 边的起始顶点的下标,从0开始v2: 边的结束顶点的下标,从0开始weight: 权值,为1表示两个顶点之间存在边,为0表示两个顶点没有边如 A——B ,v1 表示顶点A的下标0,v2表示顶点B的下标1,AB之间存在边,所以weight=1"""# 因为是无向图,所以两个顶点对应的位置都要设置边self.edges[v1][v2] = weightself.edges[v2][v1] = weightself.num_edges += 1  # 边的数量加1def show_graph(self):"""遍历邻接矩阵"""for arr in self.edges:for i in arr:print(i, end=' ')print()def get_num_vertex(self) -> int:"""返回图中的顶点个数"""return len(self.vertex_list)def get_num_edge(self) -> int:"""返回图中边的数量"""return self.num_edgesdef get_vertex_val_by_index(self, i: int) -> str:"""根据顶点下标返回顶点的值如传入下标0,返回A"""return self.vertex_list[i]def get_weight(self, v1: int, v2: int) -> int:"""返回两个顶点之间边的权值"""return self.edges[v1][v2]def test_graph():n = 5vertex_arr = ['A', 'B', 'C', 'D', 'E']graph = Graph(n)# 向图中循环添加顶点for i in vertex_arr:graph.insert_vertex(i)# 添加边graph.insert_edge(0, 1, 1)graph.insert_edge(0, 2, 1)graph.insert_edge(1, 2, 1)graph.insert_edge(1, 3, 1)graph.insert_edge(1, 4, 1)# 显示图的邻接矩阵graph.show_graph()test_graph()

图的深度优先遍历

基本介绍

代码实现

from typing import Listclass Graph:vertex_list: List[str] = []  # 存储顶点的数组edges: List[list] = []  # 存储图中各条边的邻接矩阵num_edges: int = 0  # 边的数总数is_visited: List[bool] = []  # 标记一个节点是否被访问def __init__(self, n: int):"""根据传入的顶点个数初始化顶点数组和邻接矩阵n: 图中的顶点个数"""for i in range(n):arr = []for j in range(n):arr.append(0)self.edges.append(arr)self.is_visited.append(False)def get_first_neighbor(self, index: int):"""返回节点第一个邻接节点的下标,如果节点没有邻接节点则返回-1"""for i in range(len(self.vertex_list)):if self.edges[index][i] > 0:return ireturn -1def get_next_neighbor(self, v1: int, v2: int):"""根据节点v1的前一个邻接节点的下标v2获取节点v1的下一个邻接节点的下标"""for i in range(v2 + 1, len(self.vertex_list)):if self.edges[v1][i] > 0:return ireturn -1def dfs(self, i: int):"""深度优先遍历:param i: 从节点i开始遍历:return:"""# 访问节点i,即输出它print(self.vertex_list[i], end=' -> ')self.is_visited[i] = True# 获取节点i的下一个邻接节点w = self.get_first_neighbor(i)# 如果节点i的下一个邻接节点w存在while w != -1:if not self.is_visited[w]:  # 如果w没有被访问过,则从节点w开始继续深度遍历self.dfs(w)# 如果w已经被访问过,则从节点i的另一个邻接点开始遍历w = self.get_next_neighbor(i, w)# 如果w不存在,则回退到节点v,遍历节点v的下一个邻接点# 所谓的回溯,就是返回到调用dfs()的地方继续执行def for_dfs(self):"""遍历所有顶点,看是否存在没有访问过的节点"""for i in range(self.get_num_vertex()):if not self.is_visited[i]:  # 存在没有访问过的节点,以该节点进行深度优先遍历self.dfs(i)def insert_vertex(self, vertex_val: str):"""添加顶点vertex_val: 顶点的值"""self.vertex_list.append(vertex_val)def insert_edge(self, v1: int, v2: int, weight: int = 0):"""添加边v1: 边的起始顶点的下标,从0开始v2: 边的结束顶点的下标,从0开始weight: 权值,为1表示两个顶点之间存在边,为0表示两个顶点没有边如 A——B ,v1 表示顶点A的下标0,v2表示顶点B的下标1,AB之间存在边,所以weight=1"""# 因为是无向图,所以两个顶点对应的位置都要设置边self.edges[v1][v2] = weightself.edges[v2][v1] = weightself.num_edges += 1  # 边的数量加1def show_graph(self):"""遍历邻接矩阵"""for arr in self.edges:for i in arr:print(i, end=' ')print()def get_num_vertex(self) -> int:"""返回图中的顶点个数"""return len(self.vertex_list)def test_graph():n = 5vertex_arr = ['A', 'B', 'C', 'D', 'E']graph = Graph(n)# 向图中循环添加顶点for i in vertex_arr:graph.insert_vertex(i)# 添加边graph.insert_edge(0, 1, 1)graph.insert_edge(0, 2, 1)graph.insert_edge(1, 2, 1)graph.insert_edge(1, 3, 1)graph.insert_edge(1, 4, 1)# 显示图的邻接矩阵graph.show_graph()print("深度优先遍历:", end='')graph.for_dfs()test_graph()

图的广度优先遍历

基本介绍

代码实现

from typing import Listclass Graph:vertex_list: List[str] = []  # 存储顶点的数组edges: List[list] = []  # 存储图中各条边的邻接矩阵num_edges: int = 0  # 边的数总数is_visited: List[bool] = []  # 标记一个节点是否被访问def __init__(self, n: int):"""根据传入的顶点个数初始化顶点数组和邻接矩阵n: 图中的顶点个数"""for i in range(n):arr = []for j in range(n):arr.append(0)self.edges.append(arr)self.is_visited.append(False)def get_first_neighbor(self, index: int):"""返回节点第一个邻接节点的下标,如果节点没有邻接节点则返回-1"""for i in range(len(self.vertex_list)):if self.edges[index][i] > 0:return ireturn -1def get_next_neighbor(self, v1: int, v2: int):"""根据节点v1的前一个邻接节点的下标v2获取节点v1的下一个邻接节点的下标"""for i in range(v2 + 1, len(self.vertex_list)):if self.edges[v1][i] > 0:return ireturn -1def bfs(self, i: int):"""对一个节点进行广度优先遍历:param i: 节点的下标"""que = []  # 用列表模拟队列,存储已访问过的节点# 输出节点信息print(self.vertex_list[i], end=' -> ')# 标记节点为已访问self.is_visited[i] = Trueque.append(i)  # 将已访问过的节点的下标加入队列while que:  # 队列不为空,对节点i的广度优先遍历就继续# 取出队头节点的下标uu = que.pop(0)# 获取节点u的第一个邻接节点的下标ww = self.get_first_neighbor(u)# 如果节点w存在while w != -1:# 如果节点w未被访问,则访问并将节点w入队if not self.is_visited[w]:print(self.vertex_list[w], end=' -> ')self.is_visited[w] = Trueque.append(w)# 查找节点u继节点w后的另一个邻接节点w = self.get_next_neighbor(u, w)def for_bfs(self):"""遍历所有顶点,看还有哪一个没有访问过,如果有,则从没有访问过的顶点开始广度优先遍历:return:"""for i in range(len(self.vertex_list)):if not self.is_visited[i]:self.bfs(i)def insert_vertex(self, vertex_val: str):"""添加顶点vertex_val: 顶点的值"""self.vertex_list.append(vertex_val)def insert_edge(self, v1: int, v2: int, weight: int = 0):"""添加边v1: 边的起始顶点的下标,从0开始v2: 边的结束顶点的下标,从0开始weight: 权值,为1表示两个顶点之间存在边,为0表示两个顶点没有边如 A——B ,v1 表示顶点A的下标0,v2表示顶点B的下标1,AB之间存在边,所以weight=1"""# 因为是无向图,所以两个顶点对应的位置都要设置边self.edges[v1][v2] = weightself.edges[v2][v1] = weightself.num_edges += 1  # 边的数量加1def show_graph(self):"""遍历邻接矩阵"""for arr in self.edges:for i in arr:print(i, end=' ')print()def test_graph():n = 5vertex_arr = ['A', 'B', 'C', 'D', 'E']graph = Graph(n)# 向图中循环添加顶点for i in vertex_arr:graph.insert_vertex(i)# 添加边graph.insert_edge(0, 1, 1)graph.insert_edge(0, 2, 1)graph.insert_edge(1, 2, 1)graph.insert_edge(1, 3, 1)graph.insert_edge(1, 4, 1)# 显示图的邻接矩阵graph.show_graph()print("广度优先遍历:", end='')graph.for_bfs()test_graph()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/124173.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测开(性能测试---LoadRunner)

目录 一、LoadRunner的安装 二、Loadrunner的基本概念 三、开发测试脚本——VUG 3.1 脚本录制 3.2 脚本加强 四、设计场景——Controller LoadRunner是一款开源桌面应用软件,可用来模拟用户负载完成性能测试工作,LoadRunner的功能在版本不断升级的…

JWT详解解读读

📑前言 本文主要是jwt解读文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 🌄每日一句:努力一点&#…

WebDAV之π-Disk派盘 + 读出通知

手机各种推销通知太多,如何避免那些繁琐的通知内容,做出一键就能够阅读重要通知的最佳体验,帮助您更加快速和便捷的体验到那些应用内容?推荐大家使用读出通知。 读出通知APP可以设置接收通知的app,还可以用耳机操作,操作简单,你还可以指定播报设备,还有播报的声音的设置…

数据结构 | 顺序表专题

数据结构 | 顺序表专题 文章目录 数据结构 | 顺序表专题课前准备1. 目标2. 需要的储备知识3. 数据结构相关概念 开始顺序表1、顺序表的概念及结构2、顺序表分类3、动态顺序表的实现初始化顺序表顺序表的销毁顺序表的尾插顺序表的头插检查容量顺序表的尾删打印顺序表顺序表的头删…

静态网站免费部署平台介绍

静态网站免费部署平台 静态网站是指由 HTML、CSS 和 JavaScript 等静态文件构成的网站。静态网站部署平台是用于将静态网站文件托管到服务器上的平台。 静态网站部署平台有很多,其中也有一些提供免费服务。以下是一些比较流行的免费静态网站部署平台: …

VS的QT项目找不到qt环境-解决办法

用VS创建的QT项目分享给别人时,可能会出现项目识别不到QT环境的问题,这是因为对方的QT系统环境变量的路径不同,可以在 VS的属性 -> VC目录 -> 包含目录 添加如下内容: %USERPROFILE%\AppData\Local\Microsoft\WindowsApps…

异或运算的魔法

异或运算大家都知道指的是对于两个数转准成二进制之后,相同位置上的如果同时为或者,那么异或的结果就是0,不同就是1,比如01异或00结果是01,但是时间长了相信大家都很容易记混,那么有一种很好记的方式&#…

绕WAF手法总结

云锁 被拦截 http://www.test123.com/article.php?id1%20union%20select%201,2,3 绕过 http://www.test123.com/article.php?id-1/*!36000union*//*!36000distinct*//*!36000select*/1,2,user() 360websec 被拦截 http://www.xxx.com.cn/productshow.php?id79 绕过 http:/…

机器学习笔记 - 神经辐射场(NeRF)的简要概述

一、简述 神经辐射场十分重要。在表示和渲染 3D 场景领域,神经辐射场 (NeRF) 在准确性方面取得了巨大突破。 给定底层场景的多个图像,NeRF 可以从任意视点重建该场景的高分辨率、2D 渲染图。与局部光场融合 (LLFF) 和场景表示网络 (SRN) 等现有技术相比,NeRF 更能够捕获场景…

手撕排序之直接选择排序

前言: 直接选择排序是排序中比较简单的排序,同时也是时间复杂度不是很优的排序。 思想: 本文主要讲解直接选择排序的优化版本。 我们经过一次遍历直接将该数列中最大的和最小的值挑选出来,如果是升序,就将最小的和…

【递归、搜索与回溯算法】第五节.129. 求根节点到叶节点数字之和和814. 二叉树剪枝

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:递归、搜索与回溯算法 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!&am…

.jnlp

首先配置电脑的java环境。 百度搜索jre下载,会有很多结果,一般选择官网进行下载。 下载正确的jre版本。 我的电脑是windows 64位,根据你自己电脑的情况选择版本进行下载。不懂自己电脑是多少位的可以看下一步。 查看电脑是64位还是32…

如何改善设备综合效率(OEE)并提高工厂的生产力

在现代制造业中,提高设备综合效率(Overall Equipment Efficiency,OEE)是企业追求高效生产和优化生产能力的重要目标之一。OEE是一个关键的绩效指标,可以帮助企业评估设备的利用效率、生产效率和质量水平。本文将从三个…

Spring源码-refresh(1)

1、Refresh方法简介 refresh 是Spring的核心流程,主要包含13个方法。这13个方法中主要又包含3个方法。 如图: 其中标记星号的代表主要的方法。从方法中后面的分支数据也可以看出,主要的方法中存在大量的逻辑处理,后面我们会慢慢分…

SQL-正则表达式和约束

文章目录 主要内容一.正则表达式1.操作1代码如下(示例): 2.操作2代码如下(示例): 3.操作3代码如下(示例): 4.操作4代码如下(示例): 二.约束1.主键约束 2.自增长约束3.非空约束4.唯一…

mysql 操作慢查询日志

1、mysql 批量插入300w数据 CREATE PROCEDURE test_insert_200w() BEGINDECLARE i INT;SET i1;WHILE i<3000000 DOINSERT INTO shop_user (password, telephone, username) VALUES (admin, 15510304125, concat(admin, i));SET ii1;END WHILE; END; //执行sql call test_in…

国产服务器安装onlyoffice详细教程

1.通过docker安装onlyoffice 找一台能访问互联网的服务器下载onlyoffice镜像 sudo docker pull onlyoffice/documentserver查看镜像 docker images 启动onlyoffice docker run -itd \ --name onlyoffice1 \ --restart always \ -p 8099:80 \ -v /data/docker/onlyoffice/lo…

微信小程序之投票管理

前言 对于会议管理模块&#xff0c;必不可少的当然就是我们的投票管理&#xff0c;实现真正意义上的无纸化办公&#xff0c;本期博客为大家介绍会议管理模块&#xff0c;包括发布投票及查看各类投票的状态 所用技术点 MyBatis、SpringMVC、VentUI MyBatis和SpringMVC在博客主…

最新发布!阿里云卓越架构框架重磅升级

云布道师 10 月 19 日阿里云峰会山东上&#xff0c;阿里云重磅升级《阿里云卓越架构白皮书》&#xff0c;助力企业在阿里云上构建更加安全、高效、稳定的云架构。《阿里云卓越架构白皮书》在今年的阿里云峰会粤港澳大湾区首度亮相&#xff0c;这是阿里云基于多年服务各行各业客…

数据结构基础

在计算机科学中&#xff0c;数据结构是一种数据组织、管理和存储的格式&#xff0c;它可以帮助我们实现对数据高效的访问和修改&#xff0c;更准确的说&#xff0c;数据结构是数据值的集合&#xff0c;它可以体现数据值之间的关系&#xff0c;以及可以对数据进行应用的函数或操…