javascript数据结构与算法——图和字典

javascript数据结构与算法——图和字典

由于js中封装的字典数据类型比较简单,并且在图中也能用到,所以在这里也对字典进行封装。
一、字典封装
字典中的方法:
添加->set()
判断->has()
删除->remove()
获取->get()
获取全部的key->getKeys()
获取全部的value->getValues()
长度->size()
清空->clear()

对字典封装代码:
<script>
function Dictionary() {
  // 设置字典属性
  this.items = {};
  // 设置字典的方法
  // 设置字典的方法
  Dictionary.prototype.set = function (key, value) {
    this.items[key] = value;
  } 
  // 判断字典是否存在某一个key
  Dictionary.prototype.has = function (key) {
    return this.items.hasOwnProperty(key);
  }
  // 从字典中删除某一个元素
  Dictionary.prototype.remove = function (key) {
    if (!this.has(key)) return false;
    delete this.items[key];
    return true;
  }
  // 获取value值
  Dictionary.prototype.get = function (key) {
    return this.has(key) ? this.items[key] : undefined;
  }
  // 获取全部的key
  Dictionary.prototype.getKeys = function(){
    return Object.keys(this.items);
  }
  // 获取全部的value
  Dictionary.prototype.getValues = function(){
    return Object.values(this.items);
  }
  // 获取长度size 
  Dictionary.prototype.size = function(){
    return this.getKeys().length;
  }
  // 清空字典
  Dictionary.prototype.clear = function(){
    this.items = {};
  }
}
</script>

下面封装图:
图中的定义比较多,所以这里就不一一列举,主要是举出一些比较常见的方法和属性
属性:①顶点 ②边
方法
1、添加顶点->addVert
2、添加边->addEdge
3、打印出图结构->toString
4、图的遍历
4.1广度优先遍历->bfs
4.2深度优先遍历->dfs

图的边

可以使用邻接表大致如图所示
在这里插入图片描述
可以使用邻接矩阵
在这里插入图片描述
这里我们使用字典类型来存储边与边的关系
4.1广度优先遍历(BFS)
在这里插入图片描述
按照如下顺序来进行遍历
在这里插入图片描述
实现思路: 设置三色原则,未访问过的节点设置为white,访问的节点但是其子节点没有访问完,设置为gray,完全访问完使用black颜色。使用队列的先进先出的原则,当访问到哪个节点得时候,将其子节点全部压入队列中,然后逐个取出访问。
4.2深度优先遍历(DFS)
在这里插入图片描述
实现思路:这里使用深度优先遍历,设置三色原则,未访问过的节点设置为white,访问的节点但是其子节点没有访问完,设置为gray,完全访问完使用black颜色。这里使用递归遍历即可实现
图的相关代码如下:

一、队列代码

<script>
function Quene() {
  // 1、构造初始化变量
  this.items = [];
}
// 1、设置加入元素
Quene.prototype.enQuene = function (element) {
  this.items.push(element);
}
// 2、设置删除元素
Quene.prototype.deQuene = function () {
  return this.items.shift();
}
// 3、设置查找第一个元素
Quene.prototype.front = function () {
  return this.items[0];
}
// 4、查看队列长度
Quene.prototype.size = function () {
  return this.items.length;
}
// 5、查看队列是否为空
Quene.prototype.isEmpty = function () {
  return Boolean(this.items.length);
}
// 6、将队列设置成数组
Quene.prototype.toString = function () {
  let result = " ";
  for (let i = 0; i < this.items.length; i++) {
    result += this.items[i] + " ";
  }
  return result;
}
</script>

图的实现

<script>
let dict = require("./08.字典的实现");
let Dictionary = dict.Dictionary;
let quene = require("./09.队列实现");
let Quene = quene.Quene;
// 图的封装
function Graph() {
  // 图的属性
  // 图的顶点
  this.vert = [];
  // 图的边
  this.edges = new Dictionary();
  // 图的方法
  // 1、添加顶点
  Graph.prototype.addVert = function (v) {
    this.vert.push(v);
    this.edges.set(v, []);
  }
  // 2、添加边
  Graph.prototype.addEdge = function (a, b) {
    this.edges.get(a).push(b);
    this.edges.get(b).push(a);
  }
  // 3、打印出图结构
  Graph.prototype.toString = function () {
    let result = "";
    for (let i = 0; i < this.vert.length; i++) {
      result += this.vert[i] + " ——>  "
      let Vedge = this.edges.get(this.vert[i]);
      for(let j = 0;j<Vedge.length;j++){
        result += Vedge[j] + "  ";
      }
      result += "\n";
    }
    return result;
  }
  // 4、图的遍历
  Graph.prototype.initColors = function(){
    let colors = [];
    for(let i = 0;i<this.vert.length;i++){
      colors[this.vert[i]] = "white";
    }
    return colors;
  }
  //  4.1广度优先遍历
  Graph.prototype.bfs = function(v,handler){
    // 1、进行初始化设置
    // 1.1设置颜色
    let colors = this.initColors();
    // 1.2初始化队列
    let quene_1 = new Quene();
    // 2、将传入的节点插入到队列中
    quene_1.enQuene(v);
    while(quene_1.size()!==0){
      let e = quene_1.deQuene();
      // 更改颜色
      colors[e] = "grap";
      let Vedges = this.edges.get(e);
      for(let k =0;k < Vedges.length;k++){
        // 如果节点的颜色是白色,说明没有遍历过
        if(colors[Vedges[k]] == "white"){
          quene_1.enQuene(Vedges[k]);
          colors[Vedges[k]] = "gray";
        }
      }
      handler(e);
      colors[e] = "black";
    }
  }
  //  4.2深度优先遍历
  Graph.prototype.dfs = function(v,handler){
    // 1、初始化颜色设置
    let colors = this.initColors();
    this.dfsVirst(v,colors,handler);
  }
  Graph.prototype.dfsVirst = function(v,colors,handler){
    // 处理节点
    handler(v);
    // 设置节点颜色
    colors[v] = "gray";
    let vedges = this.edges.get(v);
    for(let i =0 ;i<vedges.length;i++){
      if(colors[vedges[i]] == "white"){
        this.dfsVirst(vedges[i],colors,handler);
      }
    }
    colors[v] = "black";
  }
}
let graph = new Graph();
let arr = ['A', "B", "C", "D", "E", "F", "G", "H", "I"];
for (let i = 0; i < arr.length; i++) {
  graph.addVert(arr[i]);
}
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('B', 'E');
graph.addEdge('B', 'F');
graph.addEdge('C', 'D');
graph.addEdge('C', 'G');
graph.addEdge('D', 'G');
graph.addEdge('D', 'H');
graph.addEdge('E', 'I');

let result = "";
graph.bfs(graph.vert[0],function(v){
  result += v + "  ";
})
console.log(result);
result = "" ;
graph.dfs(graph.vert[0],function(v){
  result += v + "  ";
})
console.log(result);
</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值