dijkstra java pre_Dijkstra算法实现

fun main() {

var mapGraph = MapGraph(6)

mapGraph.addEdge(0, 1, 5)

mapGraph.addEdge(0, 5, 8)

mapGraph.addEdge(1, 4, 2)

mapGraph.addEdge(1, 2, 8)

mapGraph.addEdge(2, 3, 2)

mapGraph.addEdge(3, 5, 1)

mapGraph.addEdge(4, 3, 3)

mapGraph.dijkstra(0, 5)

}

/**

* @param sid 起始顶点

* @param tid 终止顶点

* @param weight 权重

*/

class Edge(var sid: Int, var tid: Int, var weight: Int)

/**

* @param sid 顶点编号

* @param dist 从起始顶点到该顶点的距离

*/

class Vertex(var sid: Int, var dist: Int)

class MapGraph(val size: Int) {

private var adj = Array(size) {

java.util.LinkedList()

}

fun addEdge(sid: Int, tid: Int, w: Int) {

var edge = Edge(sid, tid, w)

adj[sid].add(edge)

}

fun dijkstra(s: Int, t: Int) {

//用来还原最短路径

var predecessor = Array(size){ -1 }

var vertexes = Array(size) {

Vertex(it, Int.MAX_VALUE)

}

//小顶堆

var queue = PriorityQueue(size)

var inqueue = Array(size) { false }

vertexes[s].dist = 0

queue.add(vertexes[s])

inqueue[s] = true

while (!queue.isEmpty()) {

//取出堆顶

var minVertex: Vertex = queue.poll()!!

//最短路径产生

if (minVertex.sid == t) {

break

}

for (i in adj[minVertex.sid].indices) {

//取出一条 minVertex 相连的边

var edge = adj[minVertex.sid][i]

// minVertex -> nextVertex

var nextVertex = vertexes[edge.tid]

if (minVertex.dist + edge.weight < nextVertex.dist) {

nextVertex.dist = minVertex.dist + edge.weight

predecessor[nextVertex.sid] = minVertex.sid

if (inqueue[nextVertex.sid]) {

queue.update(nextVertex)

} else {

queue.add(nextVertex)

inqueue[nextVertex.sid] = true

}

}

}

}

printPath(s, t, predecessor)

}

private fun printPath(s: Int, t: Int, predecessor: Array) {

if (s == t) {

print("$s")

return

}

var pre = predecessor[t]

if (pre < 0) {

return

}

printPath(s, pre, predecessor)

print("->${t}")

}

}

class PriorityQueue(val size: Int) {

private val nodes: Array = Array(size) {

null

}

private var realCount = 0

fun poll(): Vertex? {

if (realCount == 0) {

return null

}

var item = nodes[0]

nodes[0] = nodes[realCount - 1]

nodes[realCount - 1] = null

realCount--

//自上而下进行堆化

heapifyUpToDown(0)

return item

}

fun add(vertex: Vertex): Boolean {

if (realCount == size) {

return false

}

nodes[realCount++] = vertex

//自下而上进行堆化

heapifyDownToUp(realCount - 1)

return true

}

fun update(vertex: Vertex): Boolean {

for (i in 0 until realCount) {

if (nodes[i]!!.sid == vertex.sid) {

nodes[i]!!.dist = vertex.dist

var p = i

while (p >= 0) {

var up = (p - 1) / 2

heapifyUpToDown(p)

if (up >= 0 && nodes[up]!!.dist <= nodes[p]!!.dist) {

break

}

p = up

}

return true

}

}

return false

}

fun isEmpty(): Boolean = realCount == 0

fun heapifyUpToDown(i: Int) {

var p = i

while (p < realCount) {

var minPos = p

var left = p * 2 + 1

var right = left + 1

if (left < realCount && nodes[left]!!.dist < nodes[minPos]!!.dist) {

minPos = left

}

if (right < realCount && nodes[right]!!.dist < nodes[minPos]!!.dist) {

minPos = right

}

if (p == minPos) {

break

}

swap(p, minPos)

p = minPos

}

}

fun heapifyDownToUp(i: Int) {

var p = i

while (p > 0) {

var up = (p - 1) / 2

if (nodes[p]!!.dist < nodes[up]!!.dist) {

swap(p, up)

p = up

} else {

break

}

}

}

fun swap(i: Int, j: Int) {

var tmp = nodes[i]

nodes[i] = nodes[j]

nodes[j] = tmp

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值