c语言实现克鲁斯卡尔算法,连通图求解最小生成树的普林姆(prim)算法和克鲁斯卡尔(kruskal)算法之JavaScript实现...

最近在看《大话数据结构》,图的算法。书中用C语言讲解的,下面用JavaScript实现普林姆(prim)算法和克鲁斯卡尔(kruskal)算法求解连通网的最小生成树

普林姆(prim)算法

// 普林姆算法寻找连通网的最小生成树

const _ = require('lodash')

// 图的邻接矩阵

const G_0 = [

[0, 10, Infinity, Infinity, Infinity, 11, Infinity, Infinity, Infinity],

[10, 0, 18, Infinity, Infinity, Infinity, 16, Infinity, 12],

[Infinity, 18, 0, 22, Infinity, Infinity, Infinity, Infinity, 8],

[Infinity, Infinity, 22, 0, 20, Infinity, 24, 16, 21],

[Infinity, Infinity, Infinity, 20, 0, 26, Infinity, 7, Infinity],

[11, Infinity, Infinity, Infinity, 26, 0, 17, Infinity, Infinity],

[Infinity, 16, Infinity, 24, Infinity, 17, 0, 19, Infinity],

[Infinity, Infinity, Infinity, 16, 7, Infinity, 19, 0, Infinity],

[Infinity, 12, 8, 21, Infinity, Infinity, Infinity, Infinity, 0],

]

function prim(G) {

'use strict'

// 初始化: 从下标为0的顶点开始计算, lowcost存入0到其他顶点的权重

let lowcost = G[0], len = G.length, adjvex = _.times(len, () => 0)

for (let i = 1; i < len; i++) {

let min = Infinity, j = 1, k = 0

while (j < len) {

// 寻找当前顶点到未加入生成树顶点中的最小权重

if (lowcost[j] != 0 && lowcost[j] < min) {

min = lowcost[j]

k = j

}

j++

}

// 打印当前寻到的最小边

console.log(adjvex[k], k)

// 设置第k个点为已加入生成树

lowcost[k] = 0

// 比较第k个点到其他未加入生成树顶点的权重与之前已加入顶点到所有点的权重

for (let m = 1; m < len; m++) {

if (lowcost[m] != 0 && G[k][m] < lowcost[m]){

lowcost[m] = G[k][m]

adjvex[m] = k

}

}

}

}

prim(G_0)

克鲁斯卡尔(kruskal)算法

/**

* Created by janeluck on 17/7/11.

*/

// 克鲁斯卡尔算法寻找连通网的最小生成树

const _ = require('lodash')

// 图的邻接矩阵

const G_0 = [

[0, 10, Infinity, Infinity, Infinity, 11, Infinity, Infinity, Infinity],

[10, 0, 18, Infinity, Infinity, Infinity, 16, Infinity, 12],

[Infinity, 18, 0, 22, Infinity, Infinity, Infinity, Infinity, 8],

[Infinity, Infinity, 22, 0, 20, Infinity, 24, 16, 21],

[Infinity, Infinity, Infinity, 20, 0, 26, Infinity, 7, Infinity],

[11, Infinity, Infinity, Infinity, 26, 0, 17, Infinity, Infinity],

[Infinity, 16, Infinity, 24, Infinity, 17, 0, 19, Infinity],

[Infinity, Infinity, Infinity, 16, 7, Infinity, 19, 0, Infinity],

[Infinity, 12, 8, 21, Infinity, Infinity, Infinity, Infinity, 0],

]

// 生成权值从小到大的边集数组

function generateEdge(G) {

'use strict'

let edge = [], len = G.length

for (let i = 0; i < len; i++) {

for (let j = i + 1; j < len; j++) {

// 排除不存在的边

if (G[i][j] !== Infinity) {

edge.push({

'begin': i,

'end': j,

'weight': G[i][j]

})

}

}

}

return _.sortBy(edge, 'weight')

}

function kruskal(G) {

'use strict'

const edge = generateEdge(G), find = function (parent, f) {

while (parent[f] > 0) {

f = parent[f]

}

return f

}

let parent = _.times(G.length, () => 0)

for (let i = 0; i < edge.length; i++) {

const n = find(parent, edge[i]['begin']), m = find(parent, edge[i]['end'])

// n与m不等, 索命此边没有与现有生成树形成环路

if (n !== m) {

// 将此边的结尾顶点放入下标为该起点的parant中

parent[n] = m

// 打印当前寻到的最小边

console.log(edge[i])

}

}

}

kruskal(G_0)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值