堆优化的Dijkstra算法
堆优化的Dijkstra算法
传统Dijkstra,在选取中转节点时,是遍历取当前最小距离节点,但是其实可利用优先队列Priority_queue优化查找过程,将时间复杂度从O((V+E)lgV)O(V2+E)
降低为O((V+E)lgV))
堆优化细节:
堆优化的主要思想就是使用优先队列来代替距起点最近元素的查找。
优先队列数据类型应该包含当前结点编号和当前节点与起点的距离
模板
class MyCompare implements Comparator<Node>{ //定义比较器,指定优先队列的规则
public int compare(Node n1,Node n2){
if( n1.step > n2.step ){
return 1;
}else{
return -1;
}
}
}
class Node{ //定义优先队列数据类型
int n; //节点编号
int step; //路径
public Node(int a,int b){
n = a ;
step = b;
}
}
Queue<Node> queue = new PriorityQueue<>(new MyCompare()); //优先队列,类型为Node
int[][] matrix = new int[N+1][N+1]; //邻接矩阵
int[] dis = new int[N+1]; //储存起点K到其他节点最短距离
int[] book = new int[N+1]; //记录已经找到最短距离的节点
dis[K] = 0; //初始化起点到起点距离为0
queue.add(new Node(K,0)); //将起点入队
while( !queue.isEmpty() ){
Node temp = queue.poll(); //取出队列中距离起点最近的节点 u
int u = temp.n;
if( book[u] == 1 ) //如果节点u已存在最小路径,就continue
continue;
book[u] = 1; //因为节点u已经是离起点最近的节点,所以标记为已找到最小路径
for(int i=1;i<N+1;i++){ //遍历所有未找到最小路径的节点
if( book[i] == 0 && matrix[u][i] != INF){ //当节点u能到达节点i时;
if(dis[i] > dis[u] + matrix[u][i]){ //如果通过节点u到节点i比直接从起点
dis[i] = dis[u] + matrix[u][i]; //到节点i距离更短,就进行松弛;
queue.add(new Node(i,dis[i])); //将更新后的节点i的值加入队列
}
}
}
}
//dis数组中保存了结果,dis[i]表示从起点到i的最短路径
例题: