图的遍历---JavaScript

两种算法可以对图进行遍历:广度优先 搜索(Breadth-First SearchBFS)和深度优先搜索Depth-First SearchDFS)。图遍历可以用来 寻找特定的顶点或寻找两个顶点之间的路径,检查图是否连通,检查图是否含有环等。

首先需要了解一下图的遍历思想:图的遍历思想是必须追踪每一个访问的节点,并且追踪哪些节点还没有被完全探索,对于两种图的遍历算法,都需要明确指出第一个被访问的顶点。完全探索一个顶点要求我们查看该顶点的每一条边。对于每一条边所连接的没有被访问过的 顶点,将其标注为被发现的,并将其加进待访问顶点列表中。

注意,为了保证算法的效率,务必访问每个顶点至多两次。连通图的每条边和顶点都会被访问到。(连通图是每两个顶点都存在路径,则是连通图,如果图的两个顶点在双向上都存在路径,则图是强连通的)

下面介绍一下,广度优先探索,此算法是从指定的第一个顶点开始遍历图,先访问其所有的相邻点通俗的说就是一层层的遍历。

这里要注意,顶底访问的标记: 

  •  白色:表示该顶点还没有被访问。
  •  灰色:表示该顶点被访问过,但并未被探索过
  •  黑色:表示该顶点被访问过且被完全探索过。

顶点v开始的广度优先搜索算法所遵循 算法:

(1) 创建一个队列Q

(2) v标注为被发现的(灰色),并将v入队列Q

(3) 如果Q非空,则运行以下步骤:

(a) uQ中出队列;

(b) 将标注u为被发现的(灰色);

(c) u所有未被访问过的邻点(白色)入队列; 

(d) u标注为已被探索的(黑色)。

function Dictionary() {
    var item = {};//注意此处是一个Object对象,不是数组中存储元素
    this.has = function (key) {
        return key in item;//判断key是不是item对象中的一个属性。
    }
    this.set = function (key, value) {
        item[key] = value;//将value设为item对象的key属性的值;添加新的值或更新一个已有的值。
    }
    this.remove = function (key) {
        if (this.has(key)) {
            delete item[key];//使用js中的delete操作符来从item中移除key属性;
            return true;
        } else {
            return false;
        }
    }
    this.get = function (key) {
        return this.has(key) ? item[key] : undefined;
    }
    this.values = function () {
        var values = [];
        for (var k in item) {
            if (this.has(k)) {
                values.push(item[k])//以数组的形式返回字典中所有的values实例的值。
            }
        }
        return values;
    }
    this.keys = function () {
        var keys = [];
        for (var k in item) {
            if (this.has(k)) {
                keys.push(k)//以数组的形式返回字典中所有的values实例的值。
            }
        }
        return keys;
    }
    this.getItems = function () {
        return item;
    }

}
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.size = function () {
        return items.length;
    };
}
function Graph() {
    var vertices = [];
    var adjList = new Dictionary();
    this.addVertex = function (v) {//添加新的顶点
        vertices.push(v);//添加顶点
        adjList.set(v, []);
    }
    this.addEdge = function (v, w) {
        adjList.get(v).push(w);//v--->w的边
        adjList.get(w).push(v);//w--->v的边,
        //如果是无向图,则有一个语句就行了。此处表述的是有向图;

    }
    this.toString = function () {
        var s = '';
        for (var i = 0; i < vertices.length; i++) {
            s += vertices[i] + ' -> ';
            var neighbors = adjList.get(vertices[i]);
            for (var j = 0; j < neighbors.length; j++) {
                s += neighbors[j] + ' ';
            } 
            s += '\n';
        }
        return s;
    };
    var initializeColor = function () {
        var color = [];
        for (var i = 0; i < vertices.length; i++) {
            color[vertices[i]] = 'white';
        }
        return color;
    }
    var initializeColor = function(){ 
        var color = [];
        for (var i=0; i<vertices.length; i++){
          color[vertices[i]] = 'white'; //{1}
        }
        return color;
      };
      this.bfs = function(v, callback){
        var color = initializeColor(), 
        queue = new Queue();   
        queue.enqueue(v);       
        while (!queue.isEmpty()){   
          var u = queue.dequeue(),    
          neighbors = adjList.get(u); 
          color[u] = 'grey';   
          for (var i=0; i<neighbors.length; i++){ 
            var w = neighbors[i];    
            if (color[w] === 'white'){  
              color[w] = 'grey';   
              queue.enqueue(w);   
            }
          }
          color[u] = 'black'; 
          if (callback) {   
            callback(u);
          }
        }
      };
}
function printNode(value) {  
    console.log('Visited vertex: ' + value);  
}
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');
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());
graph.bfs(myVertices[0], printNode);



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值