js版本图的最小生成树的prim算法的延时实现

/*最小生成树的prim算法的延时实现
标记start并从start开始,把未标记的邻接点之间的边加入优先队列pq,从pq取最短的边,边的两个端点哪个没有被标记,如果这条边上有没被标记的点,就把此边加入mst,标记该点并把该点未标记的邻接点之间的边加入优先队列pq,重复操作直到pq为空。mst即最小生成树。此方法可以不考虑start不能达到的点之间的边。
*/

//(从边有权重开始)pq和mst保存的是边,以前都是保存点
//pq应该用优先队列实现,这里取巧用js自带的api了
function deleteMin(pq){
    pq.sort(randomsort)
    return pq.shift()
}
//function lengthSort(a,b){return a[2]<b[2]?-1:1}					//可以简化成这样
function lengthSort(a,b){return a[2]-b[2]}


function lazyPrimMST(G,start){
    visit(start,G)
    while(pq.length>0){
        var e=deleteMin(pq)
        //console.log(e,"pq->",pq)
        let v=e[0]
        let w=e[1]
        if(marked[v]&&marked[w]){continue}
        mst.push(e)
        if(!marked[v]){visit(v,G)}
        if(!marked[w]){visit(w,G)}
    }
}

function visit(v,G){					
    marked[v]=true
    for(let j in G[v]){
        let e=G[v][j]
        if(!marked[e[0]]){pq.push([v,e[0],e[1]])}
    }
}

//G:[[[1,1.1],[3,2.6]],[[4,0.6],[0,1.1]],[[5,8.1]],****]
let generateGraph=require('./wgraph').generateGraph
let generateEdges=require('./wgraph').generateEdges
var V=99
console.log(es=generateEdges(V,V*3))
console.log("G-->",G=generateGraph(V,es,false))
var marked=[]
var mst=[]
var pq=[]
var start=0
lazyPrimMST(G,start)
console.log(marked,"\n",mst)


//wgraph.js
function generateEdges(V,E,maxValue=9,jd=7){
    var es=[]
    //本来精度默认10,取一位小数,测试大量数据时出现相同长度的边在验证结果时很不方便
    //比如最后一条边取[1,2,1.1]或[2,3,1.1]都可以,但验证(测试里的test方法)时会报错。所以尽量不使用等长的边
    var jingdu=Math.pow(10,jd)						
    for(let i=0;i<E;i++){
        let a=Math.floor(Math.random()*V)
        let b=Math.floor(Math.random()*V)
        let v=Math.floor(Math.random()*maxValue*jingdu)/jingdu
        es.push([a,b,v])
        //es.push([a,b,v-maxValue/2])			//随机生成正/负权重的边
    }
    return es
}

function addEdge(v,w,value,graph,allowCycle=true){
    if(v==w&&!allowCycle)return
    if(graph[v].indexOf(w)==-1){graph[v].push([w,value])}
    if(graph[w].indexOf(v)==-1){graph[w].push([v,value])}
}

//edges:[[0,2,1.1],[7,1,3.6],***]
function generateGraph(V,edges,allowCycle=true){
    var g=[]
    for(let i=0;i<V;i++){g[i]=[]}
    for(let i in edges){
        addEdge(edges[i][0],edges[i][1],edges[i][2],g,allowCycle)
    }
    return g
}
function addDirectedEdge(v,w,value,graph,allowCycle=true){
    if(v==w&&!allowCycle)return
    if(graph[v].indexOf(w)==-1){graph[v].push([w,value])}

}

function generateDirectedGraph(V,edges,allowCycle){
    var g=[]
    for(let i=0;i<V;i++){g[i]=[]}
    for(let i in edges){
        addDirectedEdge(edges[i][0],edges[i][1],edges[i][2],g,allowCycle)
    }
    return g
}

function getReverseGraph(G){
    let v=G.length
    var es=[]
    for(let i=0;i<v;i++){
        let list=G[i]
        for(let j in list){
            es.push([list[j],i])
        }
    }
    return generateDirectedGraph(v,es)
}

exports.addEdge=addEdge
exports.generateGraph=generateGraph
exports.addDirectedEdge=addDirectedEdge
exports.generateDirectedGraph=generateDirectedGraph
exports.getReverseGraph=getReverseGraph
exports.generateEdges=generateEdges

在这里插入图片描述
空间上mst和pq都与E成正比,时间上每条边只加一次,插入取出的都lgE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值