javascript数组怎么实现邻接表

最高效的方式是使用map结合set来表示邻接表,1. 当顶点编号不连续或数量大时,使用map以顶点为键存储邻居列表,避免空间浪费;2. 使用set代替数组存储邻居,使检查邻居关系的时间复杂度降为o(1);3. 对于添加和删除边操作,需在无向图中同步更新双向边,使用push和filter或set的add/delete方法实现;4. 该结构广泛应用于dfs、bfs、dijkstra等图算法,提供高效的邻接关系查询与遍历支持。

javascript数组怎么实现邻接表

在JavaScript中,数组可以巧妙地模拟邻接表,用来表示图结构。核心思路是用数组的索引代表图中的顶点,而每个索引对应的值(通常也是一个数组)则存储与该顶点相邻的顶点。

javascript数组怎么实现邻接表

解决方案:

JavaScript数组实现邻接表,关键在于利用数组的索引作为顶点,数组元素存储相邻顶点。

立即学习“Java免费学习笔记(深入)”;

javascript数组怎么实现邻接表

如何高效地用JavaScript数组表示图的邻接关系?

用JavaScript数组表示图的邻接关系,本质上是建立顶点和其相邻顶点之间的映射。最直接的方法是使用一个数组,数组的每个索引代表一个顶点,而索引对应的值则是一个数组,存储与该顶点相邻的所有顶点。

例如,如果图中有顶点0, 1, 2, 3,并且顶点0与顶点1和2相邻,顶点1与顶点0和3相邻,顶点2与顶点0相邻,顶点3与顶点1相邻,那么邻接表可以表示为:

javascript数组怎么实现邻接表

const adjacencyList = [  [1, 2], // 顶点0的邻居是1和2  [0, 3], // 顶点1的邻居是0和3  [0],    // 顶点2的邻居是0  [1]     // 顶点3的邻居是1];

这种表示方法的优点是简单直观,易于理解和实现。但是,如果图的顶点数量非常大,或者顶点编号不连续,那么使用数组可能会浪费大量的存储空间。此外,查找特定顶点的邻居的时间复杂度是O(1),但是检查某个顶点是否是另一个顶点的邻居的时间复杂度是O(n),其中n是邻居的数量。

为了解决这些问题,可以使用JavaScript的Map对象来代替数组。Map对象可以存储任意类型的键值对,因此可以使用顶点作为键,邻居列表作为值。例如:

const adjacencyList = new Map();adjacencyList.set(0, [1, 2]);adjacencyList.set(1, [0, 3]);adjacencyList.set(2, [0]);adjacencyList.set(3, [1]);

使用Map对象的好处是可以灵活地表示顶点编号不连续的图,并且可以避免浪费存储空间。但是,查找特定顶点的邻居的时间复杂度仍然是O(1),检查某个顶点是否是另一个顶点的邻居的时间复杂度仍然是O(n)。

实际上,如果需要频繁地检查某个顶点是否是另一个顶点的邻居,那么可以使用Set对象来存储邻居列表。Set对象可以高效地检查某个元素是否存在。例如:

const adjacencyList = new Map();adjacencyList.set(0, new Set([1, 2]));adjacencyList.set(1, new Set([0, 3]));adjacencyList.set(2, new Set([0]));adjacencyList.set(3, new Set([1]));

在这种表示方法中,检查某个顶点是否是另一个顶点的邻居的时间复杂度是O(1)。

选择哪种表示方法取决于具体的应用场景。如果顶点数量不大,并且顶点编号连续,那么使用数组是最简单的选择。如果顶点数量很大,或者顶点编号不连续,那么使用Map对象可以更好地利用存储空间。如果需要频繁地检查邻居关系,那么使用Set对象可以提高性能。

如何在邻接表中添加和删除边?

在基于数组的邻接表中添加边,我们需要找到对应顶点的数组,并将新的邻居添加到该数组中。删除边则需要从邻居数组中移除指定的顶点。注意,如果是无向图,则需要在两个顶点对应的数组中都进行操作。

function addEdge(graph, source, destination) {  graph[source].push(destination); // 添加边  // 如果是无向图,则需要添加反向边  // graph[destination].push(source);}function removeEdge(graph, source, destination) {  graph[source] = graph[source].filter(neighbor => neighbor !== destination);  // 如果是无向图,则需要移除反向边  // graph[destination] = graph[destination].filter(neighbor => neighbor !== source);}// 示例const adjacencyList = [[1, 2], [0, 3], [0], [1]];addEdge(adjacencyList, 0, 3); // 添加从顶点0到顶点3的边console.log(adjacencyList); // 输出:[ [ 1, 2, 3 ], [ 0, 3 ], [ 0 ], [ 1 ] ]removeEdge(adjacencyList, 0, 2); // 移除从顶点0到顶点2的边console.log(adjacencyList); // 输出:[ [ 1, 3 ], [ 0, 3 ], [ 0 ], [ 1 ] ]

需要注意的是,在实际应用中,可能需要进行错误处理,例如检查顶点是否存在,以及避免添加重复的边。

邻接表在图算法中的应用实例

邻接表是实现许多图算法的基础。例如,深度优先搜索 (DFS) 和广度优先搜索 (BFS) 都可以很方便地使用邻接表来实现。

下面是一个使用邻接表实现DFS的JavaScript示例:

function dfs(graph, startNode, visited = new Set()) {  visited.add(startNode);  console.log(`Visiting node: ${startNode}`);  for (const neighbor of graph[startNode]) {    if (!visited.has(neighbor)) {      dfs(graph, neighbor, visited);    }  }}// 示例const adjacencyList = [[1, 2], [0, 3], [0], [1]];dfs(adjacencyList, 0);// 输出:// Visiting node: 0// Visiting node: 1// Visiting node: 3// Visiting node: 2

在这个例子中,dfs 函数递归地访问图中的每个顶点。visited Set用于跟踪已经访问过的顶点,以避免无限循环。 类似地,BFS也可以使用邻接表来实现,只需要使用队列来代替递归调用即可。 此外,邻接表还可以用于实现Dijkstra算法、Prim算法等其他重要的图算法。

以上就是javascript数组怎么实现邻接表的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1512611.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 07:14:18
下一篇 2025年12月20日 07:14:26

相关推荐

  • Node.js:在JSON文件中精确保存科学计数法与固定小数位格式

    本文探讨了在Node.js应用中,如何处理JSON文件中的科学计数法数字,并确保在读写过程中保留其特定的固定小数位和指数格式。针对标准JSON序列化无法满足此特殊格式需求的问题,文章介绍了利用ES提案中的JSON.rawJSON结合自定义replacer函数的方法,实现对数字格式的精确控制,从而满足…

    2025年12月20日
    000
  • Node.js中JSON科学计数法与固定小数位格式化指南

    本文旨在解决Node.js应用在处理JSON文件时,如何将数字以特定科学计数法(如固定小数位数和指数部分补零)格式化输出的问题。尽管标准JSON解析器能正确处理数字,但当面临需要保留非标准格式以兼容特定下游应用时,传统的JSON.stringify无法满足需求。文章将深入探讨如何利用ES提案中的JS…

    2025年12月20日
    000
  • js如何创建一个没有原型的对象

    最直接的方法是使用object.create(null),1. 它创建的对象原型为null,不继承object.prototype的任何方法;2. 不具备tostring、hasownproperty等默认方法;3. __proto__为null且instanceof object返回false;4…

    2025年12月20日 好文分享
    000
  • js 如何使用groupBy对数组元素进行分组

    javascript中对数组元素进行分组的更优雅方法是使用object.groupby()。1. object.groupby()是es2024标准引入的方法,接收一个数组和一个回调函数作为参数,回调函数返回的值作为分组键,最终返回一个以分组键为属性、对应元素数组为值的普通对象;2. 与仍在stag…

    2025年12月20日
    000
  • js如何操作indexedDB

    indexeddb是浏览器提供的客户端存储方案,支持大量结构化数据的存储与复杂操作;2. 操作核心步骤包括:通过indexeddb.open()打开或创建数据库;在onupgradeneeded事件中创建对象仓库和索引;启动事务进行增删改查;3. 所有操作均为异步,需通过事件监听处理结果,建议使用p…

    2025年12月20日 好文分享
    000
  • js 怎样用countBy统计数组元素出现次数

    使用 map 替代普通对象可提升大数组的计数性能,因 map 在处理大量键值对时更高效;2. 对于超大数组,可结合 web workers 将计算移至后台线程,避免阻塞主线程;3. 当数组元素为对象时,需通过 keyextractor 函数提取唯一键(如 id)或序列化对象为稳定字符串作为计数依据,…

    2025年12月20日
    000
  • js如何将字符串转为json对象

    在javascript中将字符串转换为json对象主要使用json.parse()方法,1. 首先确保字符串符合json格式,键和字符串值必须用双引号包裹;2. 使用try-catch结构进行错误处理,防止解析失败导致程序崩溃;3. 对于包含特殊字符的字符串,需对双引号和反斜杠等进行转义处理,如使用…

    2025年12月20日
    000
  • JavaScript中根据数组动态创建对象实例的策略

    本教程探讨了在JavaScript中如何根据数组中的值,利用构造函数批量、动态地创建对象实例。针对直接使用循环创建动态变量名这一常见误区,文章提供了两种主要解决方案:将实例存储到数组中(通过 for…of 循环或 Array.prototype.map)和将实例存储到键值对对象中,并详细…

    2025年12月20日
    000
  • JavaScript:从数组动态生成对象实例的高效策略

    本文旨在探讨如何在JavaScript中根据数组中的值动态创建类的实例。我们将分析直接动态命名变量的局限性,并提供两种推荐的解决方案:将实例存储在数组中(使用for…of循环和Array.prototype.map)以及将实例存储在对象中(通过ID作为键),从而实现灵活且可维护的对象管理…

    2025年12月20日
    000
  • 动态创建JavaScript对象:从数组值到实例化对象的多种策略

    本文探讨了如何利用数组中的值动态创建JavaScript对象实例的多种高效方法。我们将详细介绍使用 for…of 循环将实例存储到数组或对象中,并重点推荐利用 Array.prototype.map 方法实现简洁的数组实例化,以及如何通过动态属性名创建可按名称访问的对象集合,避免了手动声…

    2025年12月20日
    000
  • JavaScript 中动态创建和管理对象实例的策略

    本文旨在探讨在JavaScript中如何根据数组中的值动态创建类的多个实例。我们将介绍两种主流且推荐的策略:将实例存储在数组中,可以使用for…of循环或更简洁的Array.prototype.map方法;或者将实例存储在一个对象(哈希映射)中,以便通过键名直接访问。文章将提供详细的代码…

    2025年12月20日
    000
  • js如何实现数据缓存

    选择缓存方式需根据数据生命周期和重要性权衡,内存缓存适合高频访问、临时性数据,localstorage适合需持久化的非敏感小量数据,sessionstorage适合单次会话的临时状态;2. 实现带过期时间的缓存核心是在存储时记录时间戳,读取时校验是否过期,可通过封装类在内存或localstorage…

    2025年12月20日
    000
  • js如何获取原型链上的元属性

    获取javascript对象原型链上的元属性需通过遍历原型链并提取各层级自有属性的描述符;2. 使用object.getprototypeof逐层向上遍历直至null;3. 利用reflect.ownkeys获取当前对象所有自有属性名(含symbol和非枚举属性);4. 通过object.getow…

    2025年12月20日 好文分享
    000
  • js 怎样用entries获取数组键值对的迭代器

    entries()方法返回一个迭代器对象,用于遍历数组的索引和值组成的键值对,1. 调用arr.entries()返回迭代器而非数组,需通过for…of或next()方法访问;2. 每次next()调用返回包含value(键值对)和done(是否结束)属性的对象;3. 实际应用包括同时获…

    2025年12月20日
    000
  • js如何让原型链上的属性不可劫持

    要让javascript原型链上的属性不可劫持,需使用object.defineproperty()和object.freeze()等方法防止属性被修改或删除。1. 使用object.defineproperty()可设置属性的writable为false以阻止重写,configurable为fal…

    2025年12月20日 好文分享
    000
  • 解析和处理嵌套JSON数组:提取机构名称的有效方法

    本文档旨在指导开发者如何从嵌套的JSON数组中提取数据,特别是当数组中的对象数量不确定时。我们将通过一个实际案例,展示如何使用JavaScript处理包含机构信息的JSON数据,并提供一种灵活且健壮的解决方案,避免因数组索引越界而导致程序出错。我们将使用map()和join()方法来优雅地处理嵌套数…

    2025年12月20日 好文分享
    000
  • 解析和处理嵌套JSON数组:JavaScript教程

    本文档旨在指导开发者如何使用JavaScript解析和处理包含嵌套数组的JSON数据。我们将通过一个实际案例,演示如何从嵌套的“agencies”数组中提取“raw_name”值,并将其展示在网页上。通过学习本文,你将掌握处理复杂JSON结构的技巧,并能灵活地应用于各种数据处理场景。 理解JSON结…

    2025年12月20日 好文分享
    000
  • 使用 NavLink 在 React Router 中添加查询字符串

    本文旨在介绍如何在 React Router 的 组件中添加查询字符串。由于 本身没有直接支持查询字符串的属性,本文将提供两种方法:直接将查询字符串附加到 to 属性,以及使用 useNavigate() hook 来构建包含查询字符串的导航。 方法一:直接附加到 to 属性 组件的 to 属性接受…

    2025年12月20日
    000
  • js中如何获取对象的原型链

    对象的原型链是javascript中用于查找属性和方法的路径,当对象自身无该属性时,会向上遍历原型链直至null。1. 获取原型的标准方法是object.getprototypeof(obj),返回对象的内部[[prototype]];2. 非标准但广泛支持的__proto__也可访问原型,但推荐优…

    2025年12月20日 好文分享
    000
  • javascript闭包如何模拟类静态变量

    是的,javascript可以通过闭包模拟静态变量,其核心是利用函数作用域内的变量在外部被内部函数引用时形成闭包,从而实现私有且共享的数据。1. 使用闭包的原因在于javascript缺乏原生类静态变量的私有性,闭包可实现类实例间共享且外部无法直接访问的数据,如计数器或缓存。2. 具体实现方式是通过…

    2025年12月20日 好文分享
    000

发表回复

登录后才能评论
关注微信