js封装数据结构_11_封装图结构

一、什么是图

说到图,不得不想到数学中“图”,让我们来看看维基百科怎么描述的吧:

在li'san'shu'x中,(Graph)是用于表示物体与物体之间存在某种关系的结构。数学抽象后的“物体”称作节点顶点(英语:Vertex,node或point),节点间的相关关系则称作边。在描绘一张图的时候,通常用一组点或小圆圈表示节点,其间的边则使用直线或曲线。

图的其他术语,这里就不过多陈述了,感兴趣可以去搜搜看;

二、实现思路

实现得用合适的数据结构保存顶点和边;

顶点直接使用数组即可;

边的保存可以使用二维数组(邻接矩阵)、邻接表,二维数组就是0表示无边,1表示有边,但是可能因为0过多,导致浪费性能,这里我们选择邻接表;

邻接表我用的map也就是映射来实现的,key为顶点对应的字符串,value为包含边的数组;

map的实现,我往期文章里有哦;

我们用三种颜色来表示,某个顶点的状态:白色,未被访问;灰色,访问过,未被探索;黑色,访问过且探索过;

三、方法

addVertex,增加一个顶点

addEdge,增加一条边

toString,重写toString

breadthFirstSearch,BFC遍历(广度优先搜索),传入指定的第一个被遍历的节点,以及对各个节点处理的回调函数

breadthFirstSearch,DFC遍历(深度优先搜索),传入指定的第一个被遍历的节点,以及对各个节点处理的回调函数

BFC遍历我是基于队列实现的,所以引用了一下,以前写的队列,需要的可以去看看;

因为我用的require是基于commonJs规范的,所以要用node运行,或者换成ESmodule的引用;

四、具体实现

const Dictionay = require("./13_js封装字典.js");
const Queue = require("./02_js封装队列结构");
function Graph() {
  // 属性
  this.vertexes = [];
  this.edges = new Dictionay();

  // 方法
  // 1.添加顶点
  Graph.prototype.addVertex = function (v) {
    this.vertexes.push(v);
    this.edges.set(v, []);
  };
  // 2.添加边(无向图)
  // 如果重复添加呢?
  Graph.prototype.addEdge = function (v1, v2) {
    this.edges.get(v1).push(v2);
    this.edges.get(v2).push(v1);
  };

  // 3.tostring
  Graph.prototype.toString = function () {
    let resultString = "";
    this.edges.keys().forEach((el) => {
      resultString += `${el}=>${this.edges.get(el)}
`;
    });
    return resultString;
  };

  // 4.重置颜色
  Graph.prototype.initializeColor = function () {
    let colors = [];
    for (let i = 0; i < this.vertexes.length; i++) {
      colors[this.vertexes[i]] = "white";
    }
    return colors;
  };

  // 5.BFS
  Graph.prototype.breadthFirstSearch = function (fristV, handler) {
    // 初始化颜色
    let colors = this.initializeColor();
    // 创建队列
    let queue = new Queue();
    queue.enqueue(fristV);

    while (!queue.isEmpty()) {
      let v = queue.dequeue();
      let vList = this.edges.get(v);
      vList.forEach((item) => {
        if (colors[item] == "white") {
          queue.enqueue(item);
          colors[item] = "gray";
        }
      });
      //   操作顶点
      handler(v);
      colors[v] = "black";
    }
  };

  // 深度优先
  Graph.prototype.depthFirstSearch = function (initV, handler) {
    let colors = this.initializeColor();
    this.dfsVisit(initV, colors, handler);
  };

  Graph.prototype.dfsVisit = function (v, colors, handler) {
    colors[v] = "gray";
    handler(v);
    // 访问相连的顶点
    let vList = this.edges.get(v);
    vList.forEach((item) => {
      if (colors[item] == "white") {
        this.dfsVisit(item, colors, handler);
      }
    });
    //   探索完变黑
    colors[v] = "black";
  };
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值