JS中数据结构之图

图由边的集合及顶点的集合组成。边是有方向的是有序图(有向图),否则就是无序图(无向图)。图中的一系列顶点构成路径,路径中所有的顶点都由边连接。路径的长度用路径中第一个顶点到最后一个顶点之间边的数量表示。

邻接表来表示边,即将与某一顶点的相邻的边表示为由该顶点的相邻顶点列表构成的数组,并以该顶点作为索引。比如,如果顶点 2 与顶点 0、 1、3、4 相连,那么就将0、1、3、4存储在数组中索引为 2 的位置。

Graph 类定义图

function Graph(v) {
  this.vertices = v;  //顶点的数量
  this.edges = 0;
  this.adj = [];
  for (var i = 0; i < this.vertices; ++i) {
    this.adj[i] = [];  //保存与顶点 i 相邻的顶点列表
  }
  this.addEdge = addEdge;
  this.showGraph = showGraph;
  this.dfs = dfs;
  this.bfs = bfs;
  this.marked = [];  //保存未访问过的顶点
  for (var i = 0; i < this.vertices; ++i) {
    this.marked[i] = false;
  }
  this.pathTo = pathTo;
  this.hasPathTo = hashPathTo;
  this.edgeTo = [];
}

addEdge(A,B) 添加边,先查找顶点 A 的邻接表,将顶点 B 添加到列表中,然后再查找顶点 B 的邻接表,将顶点 A 加入列表。最后,将边数加 1。

function addEdge(v, w) {
  this.ajd[v].push(w);
  this.adj[w].push(v);
  this.edges++;
}

showGraph() 方法显示所有顶点及其相邻顶点列表

function showGraph() {
  for (var i = 0; i < this.vertices; ++i) {
    var str = ‘‘;
    str += i + " -> ";
    for (var j = 0; j < this.vertices; ++j) {
      if (this.adj[i][j] != undefined) {
        str += this.adj[i][j] + ‘ ‘;
      }
    }
    console.log(str);
  }
}

搜索图

确定从一个指定的顶点可以到达其他哪些顶点,有两种搜索方法:深度优先搜索和广度优先搜索。

深度优先搜索从起始顶点开始追溯,直到到达最后一个顶点,然后回溯, 继续追溯下一条路径,直到到达最后的顶点,如此往复,直到没有路径为止。当访问一个没有访问过的顶点时,将它标记为已访问,再递归地去访问在初始顶点的邻接表中其他没有访问过的顶点。

function dfs(v) {
  this.marked[v] = true;
  if (this.adj[v] != undefined) {
    console.log("Visited vertex: " + v);
  }
  for(var w of this.adj[v]) {
    if (!this.marked[w]) {
      this.dfs(w);
    }
  }
}

//调用
g = new Graph(5);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(2, 4);
g.showGraph();
g.dfs(0);

广度优先搜索从第一个顶点开始,尝试访问尽可能靠近它的顶点。本质上,这种搜索是逐层移动的,首先检查最靠近第一个顶点的层,再逐渐向下移动到离起始顶点最远的层。

function bfs(s) {
  var queue = [];
  this.marked[s] = true;
  queue.push(s); // 添加到队尾
  while (queue.length > 0) {
    var v = queue.shift(); // 从队首移除
    if (v != undefined) {
      console.log("Visisted vertex: " + v);
    }
    for(var w of this.adj[v]) {
      if (!this.marked[w]) {this.marked[w] = true;
        queue.push(w);
      }
    }
  }
}

原文地址:https://www.cnblogs.com/wenxuehai/p/10306688.html

时间: 2024-10-10 06:18:29

JS中数据结构之图的相关文章

JS中数据结构之集合

集合(set)是一种包含不同元素的数据结构.集合中的元素称为成员.集合的两个最重要特性是:首先,集合中的成员是无序的:其次,集合中不允许相同成员存在.当你想要创建一个数据结构用来保存一些独一无二的元素时就可以用到集合. 基于数组的 Set 类的实现 function Set() { this.dataStore = []; this.add = add; this.remove = remove; this.size = size; this.union = union; //求并集 this.

JS中数据结构之排序

基本排序算法 冒泡排序:它是最慢的排序算法之一. 1.不断比较相邻的两个元素,如果前一个比后一个大,则交换位置. 2.当比较完第一轮的时候最后一个元素应该是最大的一个. 3.按照步骤一的方法进行相邻两个元素的比较,这个时候由于最后一个元素已经是最大的了,所以第二轮的时候最后一个元素不用比较,此后依次类推. function bubbleSort(arr){ for(var i=0; i<arr.length-1; i++ ){ for(var j=0; j<arr.length-1-i ;j+

JS中数据结构之检索算法(查找算法)

顺序查找 查找指定值 function seqSearch(arr, data) { for (var i = 0; i < arr.length; ++i) { if (arr[i] == data) { return true; } } return false; } 查找最小值和最大值 function findMin(arr) { var min = arr[0]; for (var i = 1; i < arr.length; ++i) { if (arr[i] < min)

编程学习之如何在Node.js中优化服务器端渲染?[图]

编程学习之如何在Node.js中优化服务器端渲染?[图]在 Airbnb,我们花了数年时间将所有前端代码迁移到 React 架构,Ruby on Rails 在 Web 应用中所占的比例每天都在减少.实际上,我们很快会转向另一个新的服务,即通过 Node.js 提供完整的服务器端渲染页面.这个服务将为 Airbnb 的所有产品渲染大部分 HTML.这个渲染引擎不同于其他后端服务,因为它不是用 Ruby 或 Java 开发的,但它也不同于常见的 I/O 密集型 Node.js 服务.一说起 Nod

JS高级-数据结构的封装

最近在看了<数据结构与算法JavaScript描述>这本书,对大学里学的数据结构做了一次复习(其实差不多忘干净了,哈哈).如果能将这些知识捡起来,融入到实际工作当中,估计编码水平将是一次质的飞跃.带着这个美好的愿望,开始学习吧O(∩_∩)O~~ 我们知道在JS中,常常用来组织数据的无非是数组和对象(这些基础就不介绍了).但在数据结构中,还有一些抽象的数据类型:列表.栈.队列.链表.字典.散列.集合.二叉树.图等,可以用来更好的对实际场景建模.当然这些数据类型,原生JS不支持,那么就需要通过封装

js中三目运算符和&amp;&amp; || 符的个人浅见

这两天看到别人写的代码,感觉很牛逼,如下,大神请忽视 $(".lgn").on("click", function() { var a = {}; a.loginType = $(this).data("logintype"); a.loginType == wx_utils.LOGIN_TYPE.WX ? (a.username = $("#username").val(), a.password = $("#pa

在Node.js中使用RabbitMQ系列一 Hello world

在前一篇文章中可伸缩架构简短系列中提到过关于异步的问题.当时推荐使用RabbitMQ来做任务队列的实现方案.本篇文章以Node.js为例子,来实际操作如何和RabbitMQ进行交互. 介绍 RabbitMQ是一个消息代理.它最初的思想特别简单:接受并且转发消息.你可以将它想象为邮局:当你将邮件放到信箱中,你可以非常肯定快件员最终会将邮件交到接受人手中.你可以把RabbitMQ比喻为信箱.邮局和快递员.RabbitMQ和邮局之间主要的区别是它不处理纸张,而是接受.存储和转发二进制数据?消息. 在R

node.js中的交互式运行环境-REPL

<Node.js权威指南>第2章Node.js中的交互式运行环境--REPL 开发者可以在该环境中很方便地输入各种JavaScript表达式并观察表达式的运行结果. 在学习Node.js框架的过程中,通过该运行环境的使用,我们可以很方便地了解Node.js中定义的各种对象所拥有的各种属性及方法.本节为大家介绍在REPL运行环境中操作变量 2.2 在REPL运行环境中操作变量 在REPL运行环境中,可以使用var关键字来定义一个变量并为其赋值,但是在输入了对其赋值进行的表达式后,该表达式的执行结

数据结构:图的实现--邻接矩阵

图结构的邻接矩阵实现 为了表现图中顶点之间的关联,我们可以使用邻接矩阵来实现图结构.所谓的邻接矩阵,就是一个反应边与边之间联系的二维数组.这个二维数组我们用matrix[numV][numV]表示,其中numV是顶点数. 对于无权图 若顶点Vi和Vj之间有边,则matrix[Vi][Vj]=1;否则matrix[Vi][Vj]=0. 对于有权图 若顶点Vi和Vj之间有边,且权值为weight,则matrix[Vi][Vj]=weight;否则matrix[Vi][Vj]=0或MAXWEIGHT(