Js-实现图的广度算法以及求最短路径

var Queue = function(){
    var items = []
    //队-存
    // var item = function(name,priority){
    //     this.name = name
    //     this.priority = priority
    // }

    this.enqueue=(elment)=>{
        items.push(elment)
    }
    //队-出
    this.dequeue=()=>{
        return items.shift()
    }
    //判断是否为空
    this.isEmpty=()=>{
        return !items.length
    }
    this.size=()=>{
        return items.length
    }
    this.getitem=()=>{
        return items
    }
}
// 栈
var Stack = function(){
    var items = []
    this.push=(element)=>{
        items.push(element)
    }
    this.pop=()=>{
        return items.pop()
    }
    this.isEmpty=()=>{
        return !items.length>0
    }
    this.size=()=>{
        return items.length
    }
    this.getitem=()=>{
        return items
    }
}


// 图遍历:广度优先和深度优先
// 广度遍历图的横向   采用队的思想
// 深度遍历图的纵向   采用递归栈的思想
// 图的遍历基本思路

// 每一个节点有三种状态

// 1.未发现 (尚未发现此节点)
// 2.已经发现 (发现其他节点连接到此,但未查找节点全部连接的节点)
// 3.已经探索 (已经发现此节点连接的全部节点)
var Graph = function(){
    // 图的定点
    var vertices = []
    // 图的边
    var adjList = {}
    // 添加图的定点 并且设置每个点对应的边为空
    this.addVertex = function(v){
        vertices.push(v)
        adjList[v]=[]
    }
    this.addEdge = function(a,b){
        // 无向连接  添加对应的各各顶点
        adjList[a].push(b)
        adjList[b].push(a)
    }
    // 打印邻接表
    this.print = function(){
        var s = '\n'
        for(var i=0;i<vertices.length;i++){
            var dindian  = vertices[i]
            s+=dindian + '=>'
            var bian = adjList[dindian]
            for(var j=0;j<bian.length;j++){
                s+=bian[j]
            }
            s += '\n'
            
        }
        console.log(s)
    }
    // white 未发现
    // grey 已发现未探索
    // black 已探索
    var initColor = function(){
        var color = {}
        for(var i=0;i<vertices.length;i++){
            color[vertices[i]]='white'
        }
        return color
    }

    // 广度遍历图
    this.bfsd = function(v,callback){
        var color = initColor()
        /*
            color= {
                'A':'white',
                'B':white
            }
        */
       var queue = new Queue()
       queue.enqueue(v)

       while(!queue.isEmpty()){
           var now = queue.dequeue()
           var bian = adjList[now]
           for(var i=0;i<bian.length;i++){
               var w = bian[i]
               if(color[w]=='white'){
                // 未发现的全部入列 并且标识为已发现
                  color[w]='grey'
                  queue.enqueue(w)
               }
           }
           color[now]='black'
           if(callback){
                callback(now)
           }
       }
    }
    // 广度遍历图 得到点的距离,以及对应的回溯点
    this.BFS = function(v,callback){
        var color = initColor()
        /*
            color= {
                'A':'white',
                'B':white
            }
        */
       var queue = new Queue()
       queue.enqueue(v)

       var d = {}//距离
       var pred = {} //回溯点
       for(var i=0;i<vertices.length;i++){
           d[vertices[i]]=0
           pred[vertices[i]]=null
       }


       while(!queue.isEmpty()){
           var now = queue.dequeue()
           var bian = adjList[now]
           for(var i=0;i<bian.length;i++){
               var w = bian[i]

               if(color[w]=='white'){
                // 未发现的全部入列 并且标识为已发现
                  color[w]='grey'
                 // 设置回溯点
                  pred[w] = now 
                  d[w]=d[now]+1
                  queue.enqueue(w)
               }
           }
           color[now]='black'
           if(callback){
                callback(now)
           }
       }
       return {
           pred,
           d
       }
    }

}
var g = new Graph()
g.addVertex('A')
g.addVertex('B')
g.addVertex('C')
g.addVertex('D')
g.addVertex('E')
g.addVertex('F')

g.addEdge('A','B')
g.addEdge('A','C')
g.addEdge('A','D')
g.addEdge('C','D')
g.addEdge('B','E')
g.addEdge('F','B')

g.addEdge('D','F')

// g.bfsd('A',function(e){console.log(e)})

// var s = g.

console.log() 
var s = g.BFS('A')

// 求出最短路径
var zuiduan  = function(from,to){
    var v = to 
    var path = new Stack()
    while(v!=from){
        // console.log(v)
        path.push(v)
        v=s.pred[v]
    }
    path.push(v)
    var str = ''
    while(!path.isEmpty()){
       str += path.pop()+'-'
    }
    str = str.slice(0,str.length-1)
    console.log(str)
}
zuiduan('A','F')


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值