JavaScript数据结构(图)

什么是图

图用来表示顶点与顶点间的关系
术语

  • 顶点:表示图中的一个结点。
  • 边:顶点与顶点间的连线。
  • 相邻顶点:一条边连接的顶点。
  • 度:一个顶点连接的边的条数。
  • 路径:路径是顶点 v1v2…,vn 的一个连续序列。
  • 根据边的有无方向分为:无向图 和 有向图。

图的表示

顶点表示

顶点的表示抽象成数字或者字母表示。

边的表示

  • 邻接矩阵:两个顶点间的边用1表示,无边连接的两个顶点间用0表示。当为带权图时,可以为权重。
    在这里插入图片描述

  • 当图为稀疏图时(顶点很多,边较少)。要用大量的0 表示两个顶点之间无边连接,已造成空间浪费。

图的封装

创建图类

  • 用一个数组存储所有的顶点
  • 字典结构来存储边的信息,key:顶点,value是一个数组,存储的是与该顶点连接的顶点。字典结构的封装
  • 方法:
    • addVertex(val) 添加一个节点
    • addEdge(val1, val2)添加一条边
    • toString() 输出一个顶点与其相邻的节点
function Graph() {
    this.vertexes = [];// 存储顶点
    this.dictonary = new Dictonary();//存储边信息
    this.dfsResult = '';// 深度优先的结果
    this.bfsResult = '';// 广度优先的结果
}
// 添加一个节点
Graph.prototype.addVertex = function(val) {
    this.vertexes.push(val);
    this.dictonary.set(val, []);
};
//添加一条边
Graph.prototype.addEdge = function(val1, val2) {
    this.dictonary.get(val1).push(val2);
    this.dictonary.get(val2).push(val1);
};
// 颜色初始化
Graph.prototype.initializeColor = function() {
    const color = [];
    this.vertexes.forEach(value => {
        color[value] = 'white';
    });
    return color;
};
//toString()
Graph.prototype.toString = function() {
    let result = '';
    this.vertexes.forEach(key => {
        result += key + ' -> '
        this.dictonary.get(key).forEach(value => {
            result += value + ' ';
        });
        result += '\n';
    });
    return result;
};

代码测试

const graph = new Graph();
graph.addVertex('A');graph.addVertex('B');
graph.addVertex('C');graph.addVertex('D');
graph.addVertex('E');graph.addVertex('F');
graph.addVertex('G');graph.addVertex('H');
graph.addVertex('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');
console.log(graph.toString());

在这里插入图片描述

图的遍历

深度优先搜索

  • 深度优先搜索算法将会从第一个指定的顶点开始遍历图,沿着路径知道这条路径最后被访问了。
  • 接着原路回退并探索吓一条路径。
  • 图解 DFS

在这里插入图片描述

代码实现

利用递归实现

//深度优先
Graph.prototype.dfs = function(startV) {
    const color = this.initializeColor();
    this.dfsVisit(startV, color);
    return this.dfsResult;

}
Graph.prototype.dfsVisit = function(vertex, color) {
    const current = this.dictonary.get(vertex);
    color[vertex] = 'gray';
    this.dfsResult += vertex + ' ';
    for (let i = 0; i < current.length; i++) {
        if (color[current[i]] === 'white') {
            this.dfsVisit(current[i], color);
        }
    }
    color[vertex] = 'black';
};

深度优先搜索代码测试

console.log(graph.dfs('A'));
// A B E I F C D G H

广度优先搜索

  • 广度优先算法会从指定的第一个顶点开始遍历图,先访问其所有的相邻点,就像一次访问图的一层。换句话说,就是先宽后深的访问顶点。
  • 图解 BFS

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEldtkdj-1618910421949)(JavaScript%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E5%9B%BE%EF%BC%89.assets/image.3vz7fx7tgvs0.png)]

代码实现

利用队列实现

队列结构的封装

// 广度优先
Graph.prototype.bfs = function(startV) {
    const color = this.initializeColor();
    let queue = new Queue();// 队列结构的定义
    queue.enqueue(startV);
    color[startV] = 'gary';
    while (!queue.isEmpty()) {
        const v = queue.dequeue();
        this.bfsResult += v + ' ';
        let outV = this.dictonary.get(v);
        for (let i = 0; i < outV.length; i++) {
            if (color[outV[i]] === 'white') {
                color[outV[i]] = 'gary';
                queue.enqueue(outV[i]);
            }
        }
        color[v] = 'black';
    }
    return this.bfsResult;
};

广度优先搜索代码测试

console.log(graph.bfs('A'));
// A B C D E F G H I 
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值