图:广度优先遍历(BFS)和深度优先遍历(DFS)

1.工具类:队列和字典

export class DictionNary {// 字典的封装constructor() {this.items = {}}set(key, value) {// 添加键this.items[key] = value}has(key){// 判断键是否存在return this.items.hasOwnProperty(key)}get(key){// 获取键的valuereturn this.has(key) ? this.items[key] : undefined}remove (key){// 删除键if(this.has(key)){delete this.items[key]return true}return false}keys(){// 获取所有的键return Object.keys(this.items)}values(){// 获取所有的值return Object}size(){// 获取键值对的数量return this.keys().length}clear(){// 清空字典this.items = {}}toString(){// 转换为字符串if(this.size() > 0){let objString = `{${this.keys().join(',')}}`return objString}else{return '{}'}}
}export class Queue {// 队列的封装constructor() {this.items = []}// 方法enqueue(element) {// 添加元素到队列this.items.push(element)}dequeue() {// 移除队列的第一个元素return this.items.shift()}front() {// 返回队列的第一个元素return this.items[0]}isEmpty() {// 判断队列是否为空return this.items.length == 0}size() {// 返回队列的元素个数return this.items.length}toString() {return this.items.toString()}}

2. 图的封装

class Graph {constructor() {// 顶点this.vertexes = []// 边this.edges = new DictionNary()}// 方法addVertex(v){// 添加顶点this.vertexes.push(v)// 顶点对于边数组的初始化this.edges.set(v, [])}addEdge(v1, v2){// 无向图中边的设置this.edges.get(v1).push(v2)this.edges.get(v2).push(v1)}toString(){let result = ''for(let i = 0; i < this.vertexes.length; i++){result += this.vertexes[i] + ' -> 'const neighbors = this.edges.get(this.vertexes[i])for(let j = 0; j < neighbors.length; j++){result += neighbors[j] + ' '}result += '\n'}return result}initializeColor(){// 顶点遍历颜色初始化const colors = []for(let i = 0; i < this.vertexes.length; i++){colors[this.vertexes[i]] = 'white'}return colors}bfs(firstVertex, callback){// 广度优先遍历// 顶点遍历测试// 1.层序遍历:Breadth-First Search (BFS)// 2.深度遍历:Depth-First Search (DFS)// 3.为了记录顶点是否被访问过,我们使用三种颜色定义顶点的状态// 1.白色:表示该顶点还没有被访问// 2.灰色:表示该顶点被访问过,但并未被探索(被探索意思是其所有相邻顶点都被访问过)// 3.黑色:表示该顶点被访问过且被完全探索// 1.初始化顶点颜色const colors = this.initializeColor()// 2.创建队列const queue = new Queue()// 3.将第一个顶点加入队列queue.enqueue(firstVertex)// 4.循环遍历队列while(!queue.isEmpty()){// 4.1.从队列中取出一个顶点const v = queue.dequeue()// 4.2.获取和该顶点相邻的顶点const neighbors = this.edges.get(v)// 4.3.将当前顶点的颜色设置为灰色(被访问过)   colors[v] = 'gray'// 4.4.遍历该顶点的所有相邻顶点for(let i = 0; i < neighbors.length; i++){const w = neighbors[i]if(colors[w] === 'white'){colors[w] = 'gray'queue.enqueue(w) }}// 4.5.将当前顶点设置为黑色(被探索)colors[v] = 'black'// 4.6.调用callback函数callback(v)}}dfs(initVertex, callback){// 1.初始化颜色const colors = this.initializeColor()// 2.递归函数this.dfsVisit(initVertex, colors, callback)}dfsVisit(vertexes, colors, callback){// 1.访问过节点置灰色colors[vertexes] = 'gray'// 2.调用callback函数callback(vertexes)// 3.获取和该顶点相邻的顶点const neighbors = this.edges.get(vertexes)for(let i = 0; i < neighbors.length; i++){const w = neighbors[i]if(colors[w] === 'white'){this.dfsVisit(w, colors, callback)}}// 4.访问完节点置黑色colors[vertexes] = 'black'}}

图测试用例

在这里插入图片描述

 const graph = new Graph()// 1.添加顶点const myVertices = ['A', 'B', 'C', 'D', 'E', 'F','G', 'H','I']for(let i = 0; i < myVertices.length; i++){graph.addVertex(myVertices[i])}// 2.添加边graph.addEdge('A', 'B')graph.addEdge('A', 'C')graph.addEdge('A', 'D')graph.addEdge('C', 'D')graph.addEdge('C', 'G')graph.addEdge('D', 'G')graph.addEdge('D', 'H')graph.addEdge('B', 'E')graph.addEdge('B', 'F')graph.addEdge('E', 'I')console.log(graph.toString())// 测试广度优先遍历let result = ''graph.bfs(graph.vertexes[0], function(v){result += v + ' '})console.log(result)// 测试深度优先遍历let deepRsult = ''graph.dfs(graph.vertexes[0], function(v){deepRsult += v + ' '})console.log(deepRsult)

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

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

相关文章

H3C ripng实验(ipv6)

H3C ripng实验&#xff08;ipv6&#xff09; 实验需求 按照图示为路由器配置IPv6地址 所有路由器运行ripng&#xff0c;进行ipv6网段的互通 查询路由表后&#xff0c;​进行全网段的ping测试&#xff0c;实验目的RTD可以ping通RTA 实验解法 按照图示为路由器配置IPv6地址 …

Simple ThFHE with poly ratio via Rényi Divergence

参考文献&#xff1a; [Renyi61] Rnyi A. On measures of entropy and information[C]//Proceedings of the fourth Berkeley symposium on mathematical statistics and probability, volume 1: contributions to the theory of statistics. University of California Press,…

【Transformer系列(5)】vision transformer(ViT)带来的思考?

一、ViT的意义 Vision Transformer&#xff08;ViT&#xff09;是一种基于Transformer架构的图像分类模型&#xff0c;它通过将图像划分为一系列的图像块&#xff08;patches&#xff09;&#xff0c;并将这些块转换为向量序列&#xff0c;然后通过Transformer的自注意力机制对…

某站戴师兄——Excel实战

1、设置下拉选项&#xff1a;数据——数据验证——设置 如下设置&#xff1a; 2、If、sumif、index、match综合应用&#xff1a; sumif(条件区域&#xff0c;条件&#xff0c;目标区域&#xff09; sumifs(目标区域,条件区域1&#xff0c;条件1,条件区域2&#xff0c;条件2) …

[渗透利器]某大佬公开自用红队渗透工具

前言 看到群里大佬发的文章&#xff0c;公开了自用的工具&#xff0c;前来拜膜一下。 使用方式 该工具首先需要初始化数据库&#xff0c;Windows推荐使用PHP Study&#xff0c;搭建更方便。 修改默认root密码后新建数据库&#xff0c;账号密码随便填&#xff0c;公网环境注意…

知识库工具:付费的HelpLook AI知识库比免费的牵牛易帮好在哪里

在知识管理的领域中&#xff0c;选择合适的知识库工具对于企业来说很重要。市面上有很多知识库产品&#xff0c;有付费的和免费的&#xff0c;但是还是有很多企业会选择使用付费的&#xff0c;而不是免费的。这是为什么呢&#xff1f;这就是今天要探讨的问题&#xff0c;下面就…

【自用】了解移动存储卡的基本信息

前言 本文是看B站视频做的一个简单笔记&#xff0c;方便日后自己快速回顾&#xff0c;内容主要介绍了存储卡基本参数&#xff0c;了解卡面上的数字、图标代表的含义。对于日后如何挑选判断一张存储卡的好坏、判别一张存储卡是否合格有一定帮助。 视频参考链接&#xff1a;【硬…

spring ioc 容器加载过程 refresh() 方法详解

IOC 加载过程 从 new ClassPathXmlApplicationContext开始 ApplicationContext context new ClassPathXmlApplicationContext("classpath:application.xml");ClassPathXmlApplicationContext类构造方法 public ClassPathXmlApplicationContext(String[] configLo…

Docker重启容器失败

Bug描述 [rootVM-12-15-centos ~]# docker restart ca1008fbdf25 Error response from daemon: Cannot restart container ca1008fbdf25: driver failed programming external connectivity on endpoint nginx_java (aded2fc7cbfa784b2e6a39e08d3ae2e7d00c13af88879a8fe7c5007…

飞腾E2000运行Zephyr操作系统

Phytium-Zephyr-SDK 1. 仓库介绍 1.1 本仓库特色 此项目是一个开源软件&#xff0c;专为物联网领域设计&#xff0c;基于Zephyr实时操作系统&#xff0c;针对Phytium系列CPU进行了专门的适配和应用开发。我们的目标是降低开发者的使用门槛&#xff0c;提供了部署文档和使用指…

Java毕设之学院党员管理系统的设计与实现

运行环境 环境说明: 开发语言:java 框架:springboot&#xff0c;vue JDK版本:JDK1.8 数据库:mysql5.7(推荐5.7&#xff0c;8.0也可以) 数据库工具:Navicat11 开发软件:idea/eclipse(推荐idea) Maven包:Maven3.3.9 系统实现 管理员功能实现 党员管理 管理员进入指定功能操作…

hadoop学习---基于hive的数仓搭建增量信息拉链表的实现

拉链表就是SCD2&#xff0c;它的优点是即满足了反应数据的历史状态&#xff0c;又能在最大程度上节省存储。 拉链表的实现需要在原始字段基础上增加两个新字段&#xff1a; start_time(表示该条记录的生命周期开始时间——周期快照时的状态)end_time(该条记录的生命周期结束时…