博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js算法: 图的两种表示方法以及广度优先算法
阅读量:6827 次
发布时间:2019-06-26

本文共 2901 字,大约阅读时间需要 9 分钟。

hot3.png

图分为有向图和无向图,图的表示方法有两种,且都可以表示有向图或者无向图:

  1. 邻接链表标示
  2. 矩阵标示

如下图:

输入图片说明

使用邻接链表标示:

北京->武汉武汉->西安->上海西安上海->北京拉萨->北京->西安

使用矩阵标示 [北京, 武汉, 上海, 西安, 拉萨]分别为 v1-v4, 1标示连通, 0标示不连通

| 0 | 1 | 0 | 0 | 0 || 0 | 0 | 1 | 1 | 0 || 1 | 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 | 0 || 1 | 0 | 0 | 1 | 0 |

使用矩阵的优点,很容易看出是否两个结点间的连通性,缺点是牺牲了存储空间

图广度优先算法,找出s源节点出发,经过最少结点到达所有结点算法:

//我们这里采用邻接链表标示图class Graph {  constructor(vertexs) {    this.adj = {};    vertexs.forEach( (vertex) => {      this.adj[vertex] = {};    })  }  addVertex(vertex) {    //添加结点    this.adj[vertex] = {};  }  /**   * @param {Edge} edge   */  addEdge(edge) {    //添加边    if (!this.adj[edge.from]) {      throw new Error(`vertex ${edge.from} 不存在`)    }    if (!this.adj[edge.to]) {      throw new Error(`vertex ${edge.to} 不存在`)    }    this.adj[edge.from][edge.to] = edge.weight;  }  neighbor(vertex) {    //结点vertex所有邻居结点    if (!this.adj[vertex]) {      throw new Error(`vertex ${vertex} 不存在`);    }    return Object.keys(this.adj[vertex]);  }  vertexs() {    //获取所有顶点    return Object.keys(this.adj);  }}class Edge {  constructor(from, to, weight) {    this.from = from;    this.to = to;    this.weight = weight;  }}var graph = new Graph(['北京', '上海', '武汉', '西安', '拉萨']);graph.addEdge(new Edge('北京', '武汉', 1));graph.addEdge(new Edge('武汉', '上海', 1));graph.addEdge(new Edge('武汉', '西安', 1));graph.addEdge(new Edge('上海', '北京', 1));graph.addEdge(new Edge('拉萨', '西安', 1));graph.addEdge(new Edge('拉萨', '北京', 1));/** * 算法逻辑: 最开始时先把所有结点标为白色,每次把将要遍历的结点染为灰色, * 遍历过的结点染为 黑色,当所有结点都为黑色时,遍历完成 * @param {Graph} graph * @param {vertex} s * @constructor */function BFS(graph, s) {  var COLOR_WHITE = 'white';  var COLOR_GRAY = 'gray';  var COLOR_BLACK = 'black';  var vertexs = {}; //临时变量存储所有结点  //把所有结点设为白色  graph.vertexs().forEach( (vertex) => {    vertexs[vertex] = {};    vertexs[vertex].color = COLOR_WHITE;    vertexs[vertex].distance = Number.POSITIVE_INFINITY;    vertexs[vertex].parent = null;  });    //从源节点s开始遍历  vertexs[s].color = COLOR_GRAY;  vertexs[s].distance = 0;    //离源节点的距离  var queue = [];    //充当先进先出队列  queue.push(s);  while(queue.length) {    let u = queue.shift(); //出列    graph.neighbor(u).forEach( (vertex) => {      if (vertexs[vertex].color == COLOR_WHITE) {        vertexs[vertex].color = COLOR_GRAY;  //开始遍历染成灰色        vertexs[vertex].parent = u;        vertexs[vertex].distance = 0; //初始化距离参数,否则为正无穷        vertexs[vertex].distance = vertexs[u].distance + 1;        queue.push(vertex);  //入列      }    })    vertexs[u].color = COLOR_BLACK;    //所有子结点及自己遍历完成,染成黑色  }  return vertexs;}//求北京这个结点都所有结点最短距离:console.info(BFS(graph, '北京'));最终输出结果:{ '北京': { color: 'black', distance: 0, parent: null },  '上海': { color: 'black', distance: 2, parent: '武汉' },  '武汉': { color: 'black', distance: 1, parent: '北京' },  '西安': { color: 'black', distance: 2, parent: '武汉' },  '拉萨': { color: 'white', distance: Infinity, parent: null } }

转载于:https://my.oschina.net/wanglihui/blog/706038

你可能感兴趣的文章
IOS 集成 ijkplayer遇到的问题
查看>>
正则表达式
查看>>
在 JS 中使用 fetch 更加高效地进行网络请求
查看>>
javascript 分页算法
查看>>
Windows 8 中取消的功能特性
查看>>
android手机root后的安全问题
查看>>
bat改ip
查看>>
SpringBoot之在Servlet2.5容器中部署war应用
查看>>
jackson 输出json到控制台
查看>>
项目申请文档提纲
查看>>
加密解密第二章:ollydbg用法
查看>>
百万PV网站架构
查看>>
N26-第四周作业
查看>>
svn服务器搭建
查看>>
在vmware安装Ubuntu桌面软件
查看>>
Ubuntu14.04使用Remastersys打包整个镜像制作iso
查看>>
MySQL之用户和权限管理
查看>>
常用的命令的使用方法
查看>>
yum命令使用方法
查看>>
使用HeartBeat实现高可用HA的配置过程详解
查看>>