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

下一步,面象对像的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)的更多相关文章

  1. (转)广度优先搜索BFS和深度优先搜索DFS

    1. 广度优先搜索介绍 广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS. 它的思想是:从图中 ...

  2. 广度优先(bfs)和深度优先搜索(dfs)的应用实例

    广度优先搜索应用举例:计算网络跳数 图结构在解决许多网络相关的问题时直到了重要的作用. 比如,用来确定在互联网中从一个结点到另一个结点(一个网络到其他网络的网关)的最佳路径.一种建模方法是采用无向图, ...

  3. matlab练习程序(广度优先搜索BFS、深度优先搜索DFS)

    如此经典的算法竟一直没有单独的实现过,真是遗憾啊. 广度优先搜索在过去实现的二值图像连通区域标记和prim最小生成树算法时已经无意识的用到了,深度优先搜索倒是没用过. 这次单独的将两个算法实现出来,因 ...

  4. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  5. 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS

    前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...

  6. 广度优先搜索(BFS)与深度优先搜索(DFS)的对比及优缺点

    深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他 ...

  7. 深度优先搜索 & 广度优先搜索

    目录 邻接表 邻接表的深度优先搜索 邻接表的广度优先搜索 临接数组 临接数组的深度优先搜索 临接数组的广度优先搜索 二叉树 二叉树的深度优先搜索 二叉树的广度优先搜索 邻接表 邻接表的深度优先搜索 假 ...

  8. 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

    1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...

  9. 回溯算法 DFS深度优先搜索 (递归与非递归实现)

    回溯法是一种选优搜索法(试探法),被称为通用的解题方法,这种方法适用于解一些组合数相当大的问题.通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量). 基本思想 将n元问题P的状态空间E表示成 ...

随机推荐

  1. innerText在谷歌、火狐浏览器下的使用

    使用innerHTML.replace(/<.+?>/gim,'')代替innerText,简单正则替换一下

  2. 我用的/etc/vimrc

    " 映射非数字/字母键, 如:ctrl,shift, alt, home,end,功能键F1~F12, 要把这些键用尖括号括起来!如: map <F3> :NERDTree< ...

  3. 如何查看mysql索引

    show index from tableName; show keys from tableName; · Table表的名称.· Non_unique如果MySQL索引不能包括重复词,则为0.如果 ...

  4. seajs模块加载与执行原理小记

    本文仅讨论具名模块的情况,即通过spm打包出来的模块. 想起ID与路径统一原则,详见https://github.com/seajs/seajs/issues/930 今天又研究了下seajs源码,源 ...

  5. Telnet是什么?

    Telnet协议是 用途一: 测试端口号 例子:测试本机的80端口是否打开 1.获得本机IP dos命令:ipconfig 可以看到本机的IP地址是192.168.0.102,当然这也是局域网IP,并 ...

  6. 简论:int i = 0

    int i =0; 或许这就是i和0的缘分吧...

  7. TaskTracker任务初始化及启动task源码级分析

    在监听器初始化Job.JobTracker相应TaskTracker心跳.调度器分配task源码级分析中我们分析的Tasktracker发送心跳的机制,这一节我们分析TaskTracker接受JobT ...

  8. cocos基础教程(11)事件分发机制

    cocos3.0的事件分发机制: 创建一个事件监听器-用来实现各种触发后的逻辑. 事件监听器添加到事件分发器_eventDispatcher,所有事件监听器有这个分发器统一管理. 事件监听器有以下几种 ...

  9. Android空间EditText的InputType属性

    android中inputType属性在EditText输入值时启动的虚拟键盘的风格有着重要的作用.这也大大的方便的操作.有时需要虚拟键盘只为字符或只为数字.所以inputType尤为重要. < ...

  10. [Unity3D]图形渲染优化、渲染管线优化、图形性能优化

    原地址:http://blog.sina.com.cn/s/blog_5b6cb9500101dmh0.html 转载请留下本文原始链接,谢谢.本文会不定期更新维护,最近更新于2013.11.09   ...