es 实现图的基本算法 图的深度优先搜索 广度优先搜索 普利姆算法

简介: es 实现图的基本算法 图的深度优先搜索 广度优先搜索 普利姆算法
// 图的查找算法
class Node {
    constructor(value) {
        this.value = value;
        this.neighbors = [];
    }
    /**
     * 深度优先查询 查询图
     * @param target {String | Number}
     * @returns {boolean} 结果
     */
    searchByDepth(target = '') {
        if (!this || target.length === 0) return false;
        // 用于保存已经找到的节点
        let exits = [];
        function _searchByDepth(node) {
            if (exits.includes(node)) return false;// 如果已经找过的节点,不用在继续查找
            else if (node.value === target) return true; // 找到了
            else {
                // 去找附近的节点,看看有没有
                exits.push(node);
                for (let i = 0, l = node.neighbors.length; i < l; i++) {
                    if (_searchByDepth(node.neighbors[i])) {
                        return true;
                    }
                }
            }
        }
        return !!_searchByDepth(this);
    }
    /**
     * 图的广度优先搜索
     * @param target {String | Number}
     * @returns {boolean} 结果
     */
    searchByWidth(target = '') {
        if (!this || target.length === 0) return false;
        let exits = []; // 用于保存已经存在的节点
        function _searchByWidth(nodesArr) {
            if (nodesArr.length === 0) return false;
            let nextNodesArr = [];
            for (let i = 0, l = nodesArr.length; i < l; i++) {
                if (nodesArr[i].value === target) return true;
                else {
                    exits.push(nodesArr[i]);
                    nextNodesArr = [...new Set([...nextNodesArr, ...nodesArr[i].neighbors])];
                    for (let j = 0, jl = nextNodesArr.length; j < jl; j++) {
                        if (exits.includes(nextNodesArr[i])) {
                            nextNodesArr.splice(i, 1);
                            j--;
                        }
                    }
                }
            }
            return _searchByWidth(nextNodesArr);
        }
        return _searchByWidth([this]);
    }
    // 普利姆算法
    /**
     * 普利姆算法 最小 生成树 加点法
     * @param nodeArr {Array} 所有的点集
     * @param distance {Array} 所有点的位置
     * @returns {Node}
     */
    prim(nodeArr, distance) {
        if (nodeArr.length !== distance.length || nodeArr.length === 0) return false;
        // 选一个开始的部落
        let nodeGroup = [nodeArr[0]];
        while (nodeGroup.length < nodeArr.length) {
            // 找到离部落最近的点
            let minDisNode = _minDisToGroup();
            // 将点放入到部落
            nodeGroup.push(minDisNode.node);
            // 将找到的点,与部落中的某个点进行连接
            minDisNode.node.neighbors.push(minDisNode.connectNode);
            minDisNode.connectNode.neighbors.push(minDisNode.node);
        }
        /**
         * 找到距离最近的点
         * @returns {{node: null, connectNode: null, dis: number}}
         * @private
         */
        function _minDisToGroup() {
            let result = {
                dis: Infinity, // 距离
                node: null,  // 找到的点
                connectNode: null, // 与部落的哪个点进行连接
            }
            for (let i = 0, l = nodeArr.length; i < l; i++) {
                let findNode = nodeArr[i];
                // 如果找到的当前点在部落中,跳出当前循环
                if (nodeGroup.includes(findNode)) continue;
                // 接下来的点不在部落中,需要进行该点到部落哪个点的距离最近
                let getNodeInfo = _compareNodeDis(findNode);
                if (getNodeInfo.dis < result.dis) {
                    result.dis = getNodeInfo.dis;
                    result.node = findNode;
                    result.connectNode = getNodeInfo.connectNode;
                }
            }
            return result;
        }
        /**
         * 找到离部落最小的距离,并且找到连接部落的哪个点
         * @param node
         * @returns {{connectNode: null, dis: number}}
         * @private
         */
        function _compareNodeDis(node) {
            let res = {
                dis: Infinity,
                connectNode: null,
            }
            // 找到该点距离部落哪个点最近
            for (let j = 0, jl = nodeGroup.length; j < jl; j++) {
                // 拿到部落的点
                let groupNode = nodeGroup[j];
                // 获取部落的点在部落的行
                let row = nodeArr.indexOf(groupNode);
                let col = nodeArr.indexOf(node);
                let dis = distance[row][col];
                if (dis < res.dis) {
                    res.dis = dis;
                    res.connectNode = groupNode;
                }
            }
            return res;
        }
        return this;
    }
}


测试:


let a = new Node('A');
let b = new Node('B');
let c = new Node('C');
let d = new Node('D');
let e = new Node('E');
a.neighbors.push(c, b);
b.neighbors.push(a, e);
c.neighbors.push(a, e, d);
d.neighbors.push(c, e);
e.neighbors.push(b, c, d);
console.log(b.searchByWidth('A')); // true
console.log(b.searchByWidth('F')); // false
console.log(b.searchByDepth('A')); // true
console.log(b.searchByDepth('F')); // false
// 图的最小生成树之prim算法
let a = new Node('A');
let b = new Node('B');
let c = new Node('C');
let d = new Node('D');
let e = new Node('E');
let nodeArr = [a, b, c, d, e];
let distance = [
    [0, 4, 6, Infinity, Infinity],
    [4, 0, Infinity, Infinity, 10],
    [6, Infinity, 0, 3, 7],
    [Infinity, Infinity, 3, 0, 2],
    [Infinity, 10, 7, 2, 0],
]


20201205105220619.png


20201205105229255.png

相关文章
|
9天前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
17 4
|
2月前
|
存储 人工智能 算法
图与树的遍历:探索广度优先、深度优先及其他遍历算法的原理与实现
图与树的遍历:探索广度优先、深度优先及其他遍历算法的原理与实现
173 0
|
10天前
|
Python
求解带有限重的三维装箱问题——启发式深度优先搜索算法
求解带有限重的三维装箱问题——启发式深度优先搜索算法
21 4
|
13天前
|
存储 算法 Java
广度优先搜索(Breadth-First Search,BFS)是一种用于图的遍历或搜索的算法。
广度优先搜索(Breadth-First Search,BFS)是一种用于图的遍历或搜索的算法。
|
6天前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)
|
9天前
|
人工智能 算法 物联网
求解三维装箱问题的启发式深度优先搜索算法(python)
求解三维装箱问题的启发式深度优先搜索算法(python)
13 0
|
9天前
|
算法 Python
利用深度优先搜索算法解决老鼠吃奶酪问题(python)
利用深度优先搜索算法解决老鼠吃奶酪问题(python)
5 0
|
13天前
|
人工智能 算法 Java
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。
|
2月前
|
存储 算法 C++
c++算法学习笔记 (8) 树与图部分
c++算法学习笔记 (8) 树与图部分
|
17天前
|
算法
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏