JS实现图

基础知识

 

无向图实现代码

function Dictionary() {
    // 定义字典存储键值对
    this.dirctionary = {};

    // 添加一个存储键值对
    Dictionary.prototype.add = function (key, value) {
        this.dirctionary[key] = value;
    }

    // 删除一个存储键值对
    Dictionary.prototype.delete = function (key) {
        if (this.dirctionary.hasOwnProperty(key)) {
            delete this.dirctionary[key];
        }
    }

    // 根据key返回一个item
    Dictionary.prototype.get = function (key) {
        return this.dirctionary.hasOwnProperty(key) ? this.dirctionary[key] : undefined;
    }
    // 打印字典
    Dictionary.prototype.toString = function () {
        for (const iterator in this.dirctionary) {
            console.log(this.dirctionary[iterator]);
        }
    }

}
function Queue() {

    this.items = [];

    Queue.prototype.enQueue = function (el) {
        this.items.push(el);
    }

    Queue.prototype.deQueue = function () {
        return this.items.shift();
    }

    Queue.prototype.front = function () {
        return this.items[0];
    }

    Queue.prototype.size = function () {
        return this.items.length;
    }

    Queue.prototype.isEmpty = function () {
        return this.items.length == 0;
    }

    Queue.prototype.toString = function () {
        var str = '';
        for (var i = 0; i < this.items.length; i++) {
            str += this.items[i];
        }
        return str;
    }
}
function Graph() {
    // 定义属性
    this.vertexes = [];             // 顶点用数组存储
    this.edage = new Dictionary();    // 边用字典存储

    // 添加顶点
    Graph.prototype.addVertex = function (v) {
        this.vertexes.push(v);
        this.edage.add(v, []);
    }
    // 添加边
    Graph.prototype.addEdage = function (v1, v2) {
        this.edage.get(v1).push(v2);
        this.edage.get(v2).push(v1);
    }

    //实现toString方法
    Graph.prototype.toString = function () {
        for (const key in this.vertexes) {
            if (this.vertexes.hasOwnProperty(key)) {
                let vertex = this.vertexes[key];            // 顶点
                let neighboringVertexs = this.edage.get(vertex);    // 相邻顶点数
                let neighboringVertexsStr = neighboringVertexs.reduce((a, b) => { return a + b + " " }, "");
                console.log(vertex + "->" + neighboringVertexsStr);
            }
        }
    }

    //初始化颜色
    Graph.prototype.initColor = function () {
        var colors = {};
        for (const key in this.vertexes) {
            if (this.vertexes.hasOwnProperty(key)) {
                colors[this.vertexes[key]] = 'white';
            }
        }
        return colors;
    }

    // 广度优先搜索
    Graph.prototype.BFS = function (firstV) {
        var result = [];
        // 1.初始化颜色
        var colors = this.initColor();
        // 2.新建队列
        var queue = new Queue();
        // 3.firstV入队,并将其颜色设置为灰色,表示被访问但是未被探索
        queue.enQueue(firstV);
        colors[firstV] = "gray";
        // 4.while循环入队与出队列
        while (!queue.isEmpty()) {
            // 4.1出队获取一个顶点,
            var v = queue.deQueue();
            // 4.2获取出队顶点的邻边顶点
            var neighboringV = this.edage.get(v);
            // 4.3for循环将颜色为白色的邻边顶点入队后,将其颜色设置为灰色,表示被访问但是未被探索。
            for (const key in neighboringV) {
                if (neighboringV.hasOwnProperty(key)) {
                    if(colors[neighboringV[key]] == "white") {
                        colors[neighboringV[key]] = "gray";
                        queue.enQueue(neighboringV[key]);
                    }
                }
            }
            // 4.4将出队顶点的颜色设置为黑色,表示被访问且被探索完毕
            colors[v] = "black";
            result.push(v);
        }
        console.log("BFS: "+ result);
    }

    // 深度优先搜索 采用闭包的形式
    Graph.prototype.DFS = function(firstV,hander) {
        // 1.初始化颜色
        var colors = this.initColor();

        // 2.调用递归函数
        digui(firstV,colors,hander,this);

        // 递归函数声明
        function digui(v,colors,hander,_this) {
        // 2.1.1将访问的V设置为灰色
        colors[v] = "gray";
        
        // 2.1.2调用闭包函数
        hander(v);

        // 2.1.3获取V的邻边顶点
        var neighboringV = _this.edage.get(v);

        // 2.1.3循环判断如果邻边顶点为白色则递归调用
        for (const key in neighboringV) {
            if (neighboringV.hasOwnProperty(key)) {
                if(colors[neighboringV[key]] == "white"){
                    digui(neighboringV[key],colors,hander,_this);
                }
            }
        }

        // 2.2将V设置为黑色
        colors[v] = "black";
        }
    }
}

var g = new Graph();
// 添加顶点
var vertexes = ["A", "B", "C", "D", "E", "F", "G", "H", "I"];
for (const key in vertexes) {
    if (vertexes.hasOwnProperty(key)) {
        g.addVertex(vertexes[key])
    }
}
// 添加边
g.addEdage("A", "B")
g.addEdage("A", "C")
g.addEdage("A", "D")
g.addEdage("C", "D")
g.addEdage("C", "G")
g.addEdage("D", "G")
g.addEdage("D", "H")
g.addEdage("B", "E")
g.addEdage("B", "F")
g.addEdage("E", "I")

g.toString();

g.BFS("A");

var result = " ";
g.DFS("A",function(v){
    result += v + " ";
});

console.log("DFS:"+result);

 

posted @ 2020-04-24 17:34  正义de键盘侠  阅读(139)  评论(0)    收藏  举报