【图】深度优先遍历&广度优先遍历

图的遍历:从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次。

因此,为了避免多次访问某一个定点,需要在遍历过程中把访问过得顶点打上标记。具体办法是设置一个访问数组 visited[n] ,初值为 0,访问过后设置为 1。

深度优先遍历(Depth_First_Search)

类似树的前序遍历。
步骤:

  1. 从图中某个顶点 v 出发,访问此顶点;
  2. 然后从 v 的未被访问的邻接点出发深度优先遍历图,直至图中所有和 v 有路径相通的顶点都被访问到。

实现

function Graph(v){
    this.v = v;
    this.e = [];
    for (var i = 0; i < this.v.length; i++) {
        this.e[i] = [];
    }
    this.visited = [];
    for (var i = 0; i < this.v.length; ++i) {
        this.visited[i] = false;
    }
}

Graph.prototype.addEdge = function (v1,v2) {
    //获取顶点对应的下标(因为这里存储的是大写字母,若存储的是顶点是number则不需要下面两步)
    var v1Index = v1.charCodeAt(0)-'A'.charCodeAt(0);
    var v2Index = v2.charCodeAt(0)-'A'.charCodeAt(0);
    this.e[v1Index].push(v2Index);
    this.e[v2Index].push(v1Index);
}
Graph.prototype.DFSTraverse = function (v) {
    //获取顶点对应的下标(因为这里存储的是大写字母,若存储的是顶点是number则不需要这一步)
    var vIndex = v.charCodeAt(0)-'A'.charCodeAt(0);
    this.visited[vIndex] = true;
    console.log("Visited vertex: " + v );
    for (var i in this.e[vIndex]){
        //console.log(this.e[vIndex][i]);
        var next_v=this.e[vIndex][i]
        if(!this.visited[next_v]){
            this.DFSTraverse(this.v[next_v]);
        }
    }
}

对下图做深度优先遍历:(右图是遍历树)
【图】深度优先遍历&广度优先遍历_第1张图片

var v= ['A','B','C','D','E','F','G','H','I'];
var g = new Graph(v);
g.addEdge(0,1);g.addEdge(0,5);
g.addEdge(1,2);g.addEdge(1,6);g.addEdge(1,8);
g.addEdge(2,3);g.addEdge(2,8);
g.addEdge(3,4);g.addEdge(3,6);g.addEdge(3,7);g.addEdge(3,8);
g.addEdge(4,5);g.addEdge(4,7);
g.addEdge(5,6);
g.addEdge(6,7);
console.log(g);

console.log("深度优先遍历过程:");
g.DFSTraverse('A');

得到的结果如下:
【图】深度优先遍历&广度优先遍历_第2张图片

广度优先遍历(Breadth_First_Search)

定义

类似树的层次遍历。
步骤:

  1. 从图中某个顶点 v 出发,访问此顶点(将其访问标志置为已被访问,即 visited[i]=1 );
  2. 依次访问顶点 v 的各个未被访问过的邻接点,将 v 的全部邻接点都访问到;
  3. 分别从这些邻接点出发,依次访问它们的未被访问过的邻接点,并使“先被访问的顶 点的邻接点”先于“后被访问的顶点的邻接点”被访问,直到图中所有已被访问过的顶点的邻接点都被访问到。
  4. 依此类推,直到图中所有顶点都被访问完为止。

广度优先搜索在搜索访问一层时,需要记住已被访问的顶点,以便在访问下层顶点时,从已被访问的顶点出发搜索访问其邻接点。
所以在广度优先搜索中需要设置一个队列 Queue ,使已被访问的顶点顺序由队尾进入队列。在搜索访问下层顶点时,先从队首取出一个已被访问的上层顶点,再从该顶点出发搜索访问它的各个邻接点。

【图】深度优先遍历&广度优先遍历_第3张图片

实现

Graph.prototype.BFSTraverse = function (v) {
    var queue = [];
    var vIndex = v.charCodeAt(0)-'A'.charCodeAt(0);
    this.visited[vIndex] = true;
    queue.push(vIndex);
    while(queue.length>0){
        var vOut =queue.shift();
        console.log("Visited vertex: " + this.v[vOut] );
        for(var i in this.e[vOut]){
            var next_v=this.e[vOut][i];
            if(!this.visited[next_v]){
                this.visited[next_v] = true;
                queue.push(next_v);
            }
        }
    }
}

运行结果:
【图】深度优先遍历&广度优先遍历_第4张图片

你可能感兴趣的:(数据结构,算法)