圖(Graph)的javascript實現

原由

最近在看《數據結構與算法--javascript描述》,而後上npmjs.org去搜索,想找合適的庫參考並記錄下來,以備之後用時能拿來即用,最沒有發現很合本身意的,因而就決定本身一一實現出來。
這是《數據結構與算法--javascript描述》學習筆記的最後一篇了,本階段學習圓滿結束^_^。javascript

npmjs相關庫

  • graph;java

  • some-graph。git

編程思路

  • 深度優先遍歷使用遞歸,但須要設定外部狀態數組,所以使用了一個小技巧;github

  • 最短路徑爲不加權的,加權的應該須要經典的Dijkstra算法,之後再繼續完善;算法

  • 注意拓撲排序與深度優先遍歷的異同;npm

  • 以模塊模式組織代碼;編程

本身的實現

Graph.js數組

(function(){
    "use strict";
    function Graph(v){
        this.vertexs = v;
        this.vertexList = [];
        this.edges = 0;
        this.adj = Object.create(null);
        this._vertex_marked = [];
        this._edgeTo = [];          //保存可達路徑
    }

    //拓撲排序
    Graph.prototype.topSort = function(){
        var stack = [];
        var visited = [];
        for(var i =0; i < this.vertexs; i++){
            visited[i] = false;
        }
        for(var i = 0; i < this.vertexs; i++){
            if(visited[i] == false){
                this.topSortHelper(i, visited, stack);
            }
        }
        var al = stack.pop();
        while(al != null){
                console.log(this.vertexList[al]);
            al = stack.pop();
        }
    };

    Graph.prototype.topSortHelper = function(v, visited, stack){
        visited[v] = true;
        for(var w in this.adj[v]){
            if(!visited[this.adj[v][w]]){
                this.topSortHelper(this.adj[v][w], visited, stack);
            }
        }
        stack.push(v);
    };

    Graph.prototype.initMarked = function(){
        for(var i = 0; i< this.vertexs; i++){
            this._vertex_marked[i] = false;
        }
    };

    Graph.prototype.pathTo = function(v){
        var start = 0;
        this.bfs(start);
        if(!this.hasPathTo(v)){
            return null;
        }
        var path = [];
        for(var i = v; i != start; i = this._edgeTo[i]){
            path.push(i);
        }
        path.push(start);
        var rs = "";
        while(path.length > 0){
            if(path.length > 1){
                rs += path.pop() + "-";
            }
            else{
                rs += path.pop();
            }
        }
        return rs;
    };

    Graph.prototype.hasPathTo = function(v){
        return this._vertex_marked[v];
    };

    //廣度優化遍歷,並生成可達路徑,爲計算無權最短路徑提供數據
    Graph.prototype.bfs = function(v){
        this.initMarked();
        var queue = [];
        this._vertex_marked[v] = true;
        queue.push(v);
        while(queue.length > 0){
            var cur = queue.shift();
            console.log("Visited vertex: " + cur);
            for(var w in this.adj[cur]){
                if(!this._vertex_marked[this.adj[cur][w]]) {
                    this._edgeTo[this.adj[cur][w]] = cur;
                    this._vertex_marked[this.adj[cur][w]] = true;
                    queue.push(this.adj[cur][w]);
                }
            }
        }
    };

    //深度優先遍歷
    Graph.prototype.dfs = function(v){
        if(arguments[1] == undefined){
            this.initMarked();
        }
        this._vertex_marked[v] = true;
        console.log("Visited vertex: " + v);
        for(var w in this.adj[v]){
            if(!this._vertex_marked[this.adj[v][w]]){
                this.dfs(this.adj[v][w],1);
            }
        }
    };

    Graph.prototype.display = function(){
        for(var i = 0; i < this.vertexs; i++){
            if(this.adj[i] == null){
                console.log(i + " --> This vertex is isolate.")
            }else{
                console.log(i + " --> " + this.adj[i].join(" "))
            }
        }
    };

    Graph.prototype.addEdge = function(v, w){
        if(this.adj[v] == null){
            this.adj[v] = [];
        }
        this.adj[v].push(w);
        if(this.adj[w] == null){
            this.adj[w] = [];
        }
        this.adj[w].push(v);
        this.edges++;
    };

    module.exports = Graph;
})();

源代碼地址

https://github.com/zhoutk/js-data-struct
http://git.oschina.net/zhoutk/jsDataStructs
相關文章
相關標籤/搜索