javascript实现的图数据结构的广度优先 搜索(Breadth-First Search,BFS)和深度优先搜索(Depth-First Search,DFS)

时间:2022-01-24 10:48:37

最后一例,搞得快。三天之内走了一次。。

下一步,面象对像的javascript编程。

function Dictionary(){
    var items = {};

    this.has = function (key) {
        return key in items;
    };

    this.set = function(key, value){
        items[key] = value;
    };

    this.remove = function(key){
        if (this.has(key)){
            delete items[key];
            return true;
        }
        return false;
    };

    this.get = function(key){
        return this.has(key) ? items[key] : undefined;
    };

    this.values = function(){
        var values = [];
        for(var k in items){
            if (this.has(k)) {
                values.push(items[k]);
            }
        }
        return values;
    };

    this.clear = function(){
        items = {};
    };

    this.size = function(){
        var count = 0;
        for (var prop in items){
            if(items.hasOwnProperty(prop)){
                ++count;
            }
        }
        return count;
    };

    this.getItems = function(){
        return items;
    };
}

function Queue() {
    var items = [];
    this.enqueue = function(element){
        items.push(element);
    }

    this.dequeue = function(){
        return items.shift();
    }

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

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

    this.clear = function(){
        items = [];
    }

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

    this.print = function(){
        console.log(items.toString());
    }
}

function Graph() {
    var vertices = [];
    var adjList = new Dictionary();

    var initializeColor = function(){
        var color = [];
        for (var i=0; i<vertices.length; i++){
            color[vertices[i]] = 'white'; //{1}
        }
        return color;
    };

    this.addVertex = function(v) {
        vertices.push(v);
        adjList.set(v, []);
    };

    this.addEdge = function(v, w){
        adjList.get(v).push(w);
        adjList.get(w).push(v);
    };

    this.bfs = function(v, callback){
        var color = initializeColor(), //{2}
            queue = new Queue(); //{3}
        queue.enqueue(v); //{4}
        while (!queue.isEmpty()){ //{5}
            var u = queue.dequeue(), //{6}
            neighbors = adjList.get(u); //{7}
            color[u] = 'grey'; // {8}
            for (var i=0; i<neighbors.length; i++){ // {9}
                var w = neighbors[i]; // {10}
                if (color[w] === 'white'){ // {11}
                    color[w] = 'grey'; // {12}
                    queue.enqueue(w); // {13}
                }
            }
            color[u] = 'black'; // {14}
            if (callback) { // {15}
                callback(u);
            }
        }
    };

    this.dfs = function(callback){
        var color = initializeColor(); //{1}
        for (var i=0; i<vertices.length; i++){ //{2}
            if (color[vertices[i]] === 'white'){ //{3}
                dfsVisit(vertices[i], color, callback); //{4}
            }
        }
    };
    var dfsVisit = function(u, color, callback){
        color[u] = 'grey'; //{5}
        if (callback) { //{6}
            callback(u);
        }
        var neighbors = adjList.get(u); //{7}
        for (var i=0; i<neighbors.length; i++){ //{8}
            var w = neighbors[i]; //{9}
            if (color[w] === 'white'){ //{10}
                dfsVisit(w, color, callback); //{11}
            }
        }
        color[u] = 'black'; //{12}
    };

    this.toString = function(){
        var s = '';
        for (var i=0; i<vertices.length; i++){ //{10}
            s += vertices[i] + ' -> ';
            var neighbors = adjList.get(vertices[i]); //{11}
            for (var j=0; j<neighbors.length; j++){ //{12}
                s += neighbors[j] + ' ';
            }
            s += '\n'; //{13}
        }
        return s;
    };
}

var graph = new Graph();
var myVertices = ['A','B','C','D','E','F','G','H','I'];
for (var i=0; i<myVertices.length; i++){
    graph.addVertex(myVertices[i]);
}
graph.addEdge('A', 'B'); //{9}
graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('C', 'D');
graph.addEdge('C', 'G');
graph.addEdge('D', 'G');
graph.addEdge('D', 'H');
graph.addEdge('B', 'E');
graph.addEdge('B', 'F');
graph.addEdge('E', 'I');

console.log(graph.toString());

function printNode(value){ //{16}
    console.log('Visited vertex: ' + value); //{17}
}
graph.bfs(myVertices[0], printNode); //{18}
graph.dfs(printNode);

javascript实现的图数据结构的广度优先 搜索(Breadth-First Search,BFS)和深度优先搜索(Depth-First Search,DFS)