javascript实现图的广度优先搜索、深度优先搜素

来源:互联网 发布:兰州知豆电动车租赁app 编辑:程序博客网 时间:2024/06/04 20:15

用邻接表表示图:

如下图所示的图:
这里写图片描述
用邻接表二维数组表示为:

adj[0] = [1,2,5,6];adj[1] = [0,3,8,9];adj[2] = [0,4];adj[3] = [1];adj[4] = [2];adj[5] = [0,7];adj[6] = [0];adj[7] = [5];adj[8] = [1];adj[9] = [1]



构建图类:

    function Graph(v){                this.vertices = v;//顶点数                this.edges = 0;//边数                this.adj = [];//数组this.adj用来存放每个每个顶点的临接表                this.visited = [];//深度度优先搜索的是否访问标志                this.visited_2 = [];// 广度优先搜索的是否访问标志                for (var i = 0; i < this.vertices; i++){                    this.adj[i] = [];                    this.visited.push(false);                    this.visited_2.push(false);                }            }    Graph.prototype = {      //存放方法



添加边

addEdge: function(a, b){            // a、b为节点            this.adj[a].push(b);            this.adj[b].push(a);            this.edges ++;//把总边数增加1        }



显示整个表

    showGraph: function(){            for (var i = 0; i < this.vertices; i ++){                console.log(i + '=>');                for (var j = 0; j < this.vertices; j ++){                    if (this.adj[i][j]){                      console.log(this.adj[i][j]);                    }                }            }        }



深度优先搜索

利用递归的思想,访问一个没有访问过的顶点,将它标记为已经访问,再递归的去访问在初始顶点的邻接表中的其他没有访问的节点;

// 深度优先搜索dfs: function(vertice){     this.visited[vertice] = true;     console.log(vertice);     for (var i = 0; i < this.adj[vertice].length; i++){       var curVertice = this.adj[vertice][i];       if (!this.visited[curVertice]){            this.dfs(curVertice);       }      }}



广度优先搜索

广度优先搜索从第一个顶点开始,尝试访问尽可能靠近它的节点,有点类似树的层序遍历;

    //广度优先搜索        bfs: function(vertice){            var that = this;            var queue = [];            queue.push(vertice);            this.visited_2[vertice] = true;            // 当队列不为空时,循环进行;            while (queue.length > 0){              var curVertice = queue.shift();              console.log(curVertice);              this.adj[curVertice].forEach(function(item){                    if (!that.visited_2[item]){                        that.visited_2[item] = true;                        queue.push(item);                    }              })            }        }



实例化图,并使用深度优先搜索、广度优先搜索

创建树,新建边

  var graph = new Graph(10);          graph.addEdge(0, 1);          graph.addEdge(0, 2);          graph.addEdge(0, 5);          graph.addEdge(0, 6);          graph.addEdge(1, 3);          graph.addEdge(1, 8);          graph.addEdge(1, 9);          graph.addEdge(2, 4);          graph.addEdge(5, 7);

显示图的结构:(邻接表):

 graph.showGraph();

这里写图片描述



深度优先搜索:

 graph.dfs(0);

这里写图片描述


广度优先搜索

 graph.bfs(0);

这里写图片描述



寻找两点间的最短路径

首先在原型对象中写入一个allDistance函数,出入一个节点为参数,返回这个节点到其他所有节点的无权距离,用数组表示;

//无权图的单源最短路径的算法        allDistance: function(vertice){            var distance = [];            // 初始化distance数组,用来存放所有的距离            for (var i = 0; i < this.vertices; i++){                distance.push(-1);            }            var that = this;            var queue = [];            queue.push(vertice);            distance[vertice] = 0;            // 当队列不为空时,循环进行;            while (queue.length > 0){              //从队列中弹出一个节点              var curVertice = queue.shift();              //遍历与当前节点相邻的所有节点              this.adj[curVertice].forEach(function(item){                    // 如果item没有被访问过                    if (distance[item] < 0){                        distance[item] = distance[curVertice] + 1;                        queue.push(item);                    }              })            }            return distance;        }


然后定义一个minDistance函数:返回从v点到w点的距离:

minDistance: function(v, w){          //先求出v到所有节点的距离              var distance = this.allDistance(v);          return distance[w];        }


验证一下:
在前面那个图实例中,

console.log(graph.minDistance(3,7));//4console.log(graph.minDistance(1,2));//2
阅读全文
0 0