Javascript数据结构——图Graph

当然,让我们深入探讨一下JavaScript中的图数据结构,并列出一些常见的面试题及其代码示例。

图数据结构详解

图(Graph)是一种非线性的数据结构,由节点(也称为顶点)和连接这些节点的边组成。节点可以表示实体(如人、地点、事物等),而边则表示这些实体之间的关系。图可以分为有向图和无向图:

  • 有向图(Directed Graph):边有方向,即从一个节点指向另一个节点。
  • 无向图(Undirected Graph):边没有方向,表示两个节点之间的连接。
图的表示方法
  1. 邻接矩阵(Adjacency Matrix)

    • 使用一个二维数组表示,如果节点i和节点j之间有边,则数组[i][j]为1(或边的权重),否则为0。
    • 优点:查找边是否存在很快(O(1))。
    • 缺点:空间复杂度较高,尤其是稀疏图(边的数量远小于节点对数量的图)。
  2. 邻接表(Adjacency List)

    • 使用一个数组或链表数组表示,每个节点对应一个链表,链表中存储该节点连接的所有节点。
    • 优点:空间复杂度较低,适合稀疏图。
    • 缺点:查找边是否存在的时间复杂度较高(O(V))。
图的遍历
  1. 深度优先搜索(DFS, Depth-First Search)

    • 使用栈(递归或显式栈)遍历节点,尽可能深入搜索每一个分支。
    • 可以用递归或迭代实现。
  2. 广度优先搜索(BFS, Breadth-First Search)

    • 使用队列逐层遍历节点。
    • 常用于寻找最短路径(在无权图中)。

常见面试题及其代码

  1. 判断图是否有环(DFS)
function hasCycle(graph) {const visited = new Set();const recursionStack = new Set();function dfs(node) {if (recursionStack.has(node)) return true;if (visited.has(node)) return false;visited.add(node);recursionStack.add(node);for (const neighbor of graph[node] || []) {if (dfs(neighbor)) return true;}recursionStack.delete(node);return false;}for (const node in graph) {if (dfs(node)) return true;}return false;
}
  1. 图的深度优先遍历(DFS)
function dfsTraversal(graph, start, visited = new Set()) {if (visited.has(start)) return;visited.add(start);console.log(start);for (const neighbor of graph[start] || []) {dfsTraversal(graph, neighbor, visited);}
}
  1. 图的广度优先遍历(BFS)
function bfsTraversal(graph, start) {const queue = [start];const visited = new Set();while (queue.length > 0) {const node = queue.shift();if (!visited.has(node)) {visited.add(node);console.log(node);for (const neighbor of graph[node] || []) {if (!visited.has(neighbor)) {queue.push(neighbor);}}}}
}
  1. 计算图的拓扑排序(Kahn’s Algorithm)
function topologicalSort(graph) {const inDegree = {};const result = [];const queue = [];// Initialize in-degree mapfor (const node in graph) {inDegree[node] = 0;}// Calculate in-degreesfor (const node in graph) {for (const neighbor of graph[node] || []) {inDegree[neighbor] = (inDegree[neighbor] || 0) + 1;}}// Enqueue nodes with zero in-degreefor (const node in inDegree) {if (inDegree[node] === 0) {queue.push(node);}}// Process nodeswhile (queue.length > 0) {const node = queue.shift();result.push(node);for (const neighbor of graph[node] || []) {inDegree[neighbor]--;if (inDegree[neighbor] === 0) {queue.push(neighbor);}}}// If there was a cycle, not all nodes would be visitedreturn result.length === Object.keys(graph).length ? result : [];
}
  1. 计算所有节点对之间的最短路径(Floyd-Warshall Algorithm)
function floydWarshall(graph) {const n = Object.keys(graph).length;const dist = JSON.parse(JSON.stringify(graph));for (let k = 0; k < n; k++) {for (let i = 0; i < n; i++) {for (let j = 0; j < n; j++) {if (dist[i][k] !== Infinity && dist[k][j] !== Infinity && dist[i][k] + dist[k][j] < dist[i][j]) {dist[i][j] = dist[i][k] + dist[k][j];}}}}return dist;
}
  1. 检测二分图(Bipartite Graph)
function isBipartite(graph) {const colors = {};const queue = [];function bfs(node, color) {colors[node] = color;queue.push(node);while (queue.length > 0) {const currentNode = queue.shift();const currentColor = colors[currentNode];for (const neighbor of graph[currentNode] || []) {if (!colors[neighbor]) {colors[neighbor] = -currentColor;queue.push(neighbor);} else if (colors[neighbor] === currentColor) {return false;}}}return true;}for (const node in graph) {if (!colors[node]) {if (!bfs(node, 1)) {return false;}}}return true;
}
  1. 图的最小生成树(Prim’s Algorithm)
function primMST(graph) {const n = Object.keys(graph).length;const key = new Array(n).fill(Infinity);const parent = new Array(n).fill(-1);const inMST = new Array(n).fill(false);key[0] = 0;parent[0] = -1;for (let count = 0; count < n - 1; count++) {let u = -1, min = Infinity;for (let v = 0; v < n; v++) {if (!inMST[v] && key[v] < min) {u = v;min = key[v];}}inMST[u] = true;for (const v of graph[u] || []) {if (!inMST[v] && graph[u][v] < key[v]) {parent[v] = u;key[v] = graph[u][v];}}}// Construct MSTconst mst = [];for (let i = 1; i < n; i++) {mst.push([parent[i], i, graph[parent[i]][i]]);}return mst;
}
}

图的克鲁斯克尔算法(Kruskal’s Algorithm)

class UnionFind {constructor(n) {this.parent = new Array(n);for (let i = 0; i < n; i++) {this.parent[i] = i;}}find(u) {if (this.parent[u] !== u) {this.parent[u] = this.find(this.parent[u]); // 路径压缩,使得后续查找更快}return this.parent[u];}union(u, v) {let rootU = this.find(u);let rootV = this.find(v);if (rootU !== rootV) {this.parent[rootU] = rootV;}}
}function kruskalMST(graph) {// 图的表示:graph = [ [u, v, weight], ... ]let edges = graph.slice().sort((a, b) => a[2] - b[2]); // 排序边let n = new Set(); // 存储所有顶点for (let edge of edges) {n.add(edge[0]);n.add(edge[1]);}let uf = new UnionFind(n.size);let mst = [];let mstCost = 0;for (let edge of edges) {let u = edge[0];let v = edge[1];let weight = edge[2];if (uf.find(u) !== uf.find(v)) {uf.union(u, v);mst.push(edge);mstCost += weight;}}return {mst: mst,cost: mstCost};
}// 示例使用
let graph = [[0, 1, 10],[0, 2, 6],[0, 3, 5],[1, 3, 15],[2, 3, 4]
];let result = kruskalMST(graph);
console.log("Edges in MST:", result.mst);
console.log("Total cost of MST:", result.cost);

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

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

相关文章

算法-判断一个数是不是3的次幂

给定一个整数&#xff0c;写一个函数来判断它是否是 3 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 3 的幂次方需满足&#xff1a;存在整数 x 使得 n 3x 示例 1&#xff1a; 输入&#xff1a;n 27 输出&#xff1a;true示…

多光谱图像的处理和分析方法有哪些?

一、预处理方法 1、辐射校正&#xff1a; 目的&#xff1a;消除或减少传感器本身、大气条件以及太阳光照等因素对多光谱图像辐射亮度值的影响&#xff0c;使得图像的辐射值能够真实反映地物的反射或发射特性。 方法&#xff1a;包括传感器校正和大气校正。传感器校正主要是根…

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全&#xff1a;现代企业的必修课 在现代技术生态中&#xff0c;应用程序编程接口&#xff08;API&#xff09;扮演着不可或缺的角色。从数据共享到跨平台集成&#xff0c;API 成为连接企业系统与外部服务的桥梁。然而&#xff0c;伴随云计算的普及与微服务架构的流行…

多个DataV遍历生成

DataV是数据可视化工具 与Echart类似 相对Echart图标边框 装饰可选官网DataV 安装 npm install kjgl77/datav-vue3main.ts import DataVVue3 from kjgl77/datav-vue3 app.use(DataVVue3)多个DataV遍历生成 Vue3viteDataV为例:<template><div w50rem h25rem flex&qu…

小程序租赁系统的优势与应用探索

内容概要 小程序租赁系统&#xff0c;听起来很高大上&#xff0c;但实际上它比你想象的要实用得多&#xff01;设想一下&#xff0c;几乎所有的租赁需求都能通过手机轻松解决。这种系统的便捷性体现在让用户随时随地都能发起租赁请求&#xff0c;而不再受制于传统繁琐的手续。…

40.3 prometheus预聚合源码解读

本节重点介绍 : 预聚合原理总结源码解读 预聚合原理总结 prometheus把record记录当做和alert一样处理进行instant_query查询当前点&#xff0c;如果是alert则走报警的流程如果是record&#xff0c;那么将查询到的结果写入tsdb&#xff0c;新的metric_name使用配置中设置的re…

driftingblues2

修改网卡配置信息 首先kali终端运行以下命令查看靶机ip 这里我们发现并没有查到靶机的ip&#xff0c;这时我们重启靶机 打开靶机&#xff0c;按下e键&#xff0c;进入到如下界面 将ro替换为rw signie init/bin/bash 替换完毕后&#xff0c;按下Ctrl键X键&#xff0c;进入如下…

Redis 使用redisTemplate获取某个规则下的key的全量数据(示例Set结构)

如下是redis中存储的数据结构 我想取key以favorites:结尾的所有数据 Redis 的 SCAN 命令用于迭代数据库中的键&#xff0c;支持通过模式过滤结果。模式规则基于 Redis 的通配符匹配语法&#xff0c;类似于文件名匹配规则&#xff1a; *&#xff1a;匹配零个或多个字符。?&…

1月2日作业

工人管理系统 #include<myhead.h> #include<sqlite3.h> sqlite3 * creat_sqlite()//创建数据库并返回数据库句柄 {const char *p"./my.db";sqlite3 *ppDb;if(sqlite3_open(p,&ppDb)!SQLITE_OK)//调用数据库提供的第三方库函数{printf("打开数据…

职场常用Excel基础03-自定义排序

大家好&#xff0c;今天和大家一起分享一下excel中的自定义排序~ 通过排序&#xff0c;用户可以快速地对表格中的数据进行整理&#xff0c;以便更直观地观察趋势、查找特定信息或为后续的数据分析做准备。除了标准的升序和降序排序外&#xff0c;Excel还提供了强大的自定义排序…

批量读取pdf发票中二维码的信息

如下代码Java类&#xff1a; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.metadata.Writ…

计算机网络-L2TP Over IPSec基础实验

一、概述 上次我们进行了标准L2TP的配置&#xff0c;但是在最后我们在进行业务流量访问时看到流量是没有进行加密的&#xff0c;这就导致可能得安全风险&#xff0c;所以这里其实可以退像GRE那样调用IPSec框架来进行加密保护。 拓扑 数据不加密 现在需要配置IPSec&#xff0c;然…

STLG_01_03_程序设计C语言 - 语法基础

C语言的语法基础是理解和使用C语言的关键。C语言的语法相对简洁&#xff0c;但功能强大。以下是C语言语法基础的主要内容&#xff1a; 一. 基本结构 1. 预处理指令&#xff1a;预处理指令以#开头&#xff0c;用于包含头文件、定义宏、条件编译等。 #include <stdio.h> …

C#控件开发4—仪表盘

目录 思路&#xff08;GDI绘图&#xff09;1.定义属性2.绘制图形3.最后生成&#xff08;自定义各种监控值显示&#xff09;End 如何让温度、湿度、压力等有量程的监控值如仪表盘&#xff08;DashBoard&#xff09;一样显示&#xff1f; 思路&#xff08;GDI绘图&#xff09; 定…

【内含代码】Spring Boot整合深度学习框架DJL

“ Deep Java Library是一个用于处理大规模数据处理和分析的强大工具包&#xff0c;它提供了丰富的数据结构和算法实现&#xff0c;支持高效的并行计算和分布式处理。Deep Java Library的设计目标是简化大规模数据处理任务的复杂性&#xff0c;提供高性能的计算能力&#xff0c…

ThinkPHP 8高效构建Web应用-第一个简单的MVC应用示例

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 我们先实现一…

数字化供应链创新解决方案在零售行业的应用研究——以开源AI智能名片S2B2C商城小程序为例

摘要&#xff1a; 在数字化转型的浪潮中&#xff0c;零售行业正经历着前所未有的变革。特别是在供应链管理方面&#xff0c;线上线下融合、数据孤岛、消费者需求多样化等问题日益凸显&#xff0c;对零售企业的运营效率与市场竞争力构成了严峻挑战。本文深入探讨了零售行业供应…

React基础知识学习

学习React前端框架是一个系统而深入的过程&#xff0c;以下是一份详细的学习指南&#xff1a; 一、React基础知识 React简介 React是一个用于构建用户界面的JavaScript库&#xff0c;由Facebook开发和维护。它强调组件化和声明式编程&#xff0c;使得构建复杂的用户界面变得更…

RabbitMQ - 4 ( 22000 字 RabbitMQ 入门级教程 )

一&#xff1a; RabbitMQ 高级特性 前面主要讲解了 RabbitMQ 的概念和应用。RabbitMQ 实现了 AMQP 0-9-1 规范&#xff0c;并在此基础上进行了多项扩展。在 RabbitMQ 官方网站中详细介绍了其特性&#xff0c;我们将其中一些重要且常用的特性挑选出来进行讲解。 1.1 消息确认 …

mac m2 安装 docker

文章目录 安装1.下载安装包2.在downloads中打开3.在启动台打开打开终端验证 修改国内镜像地址小结 安装 1.下载安装包 到官网下载适配的安装包&#xff1a;https://www.docker.com/products/docker-desktop/ 2.在downloads中打开 拖过去 3.在启动台打开 选择推荐设置 …