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

用邻接表表示图:

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

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));//4
console.log(graph.minDistance(1,2));//2
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值