参考视频
存放边的距离信息,使用优先队列PriorityQueue;
存放最短距离的点,使用ArrayList;
import java.io.*;
import java.util.*;
import java.lang.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.stream.Collectors;
class Edge{
public Node from;
public Node to;
public int weight;
public Edge(Node from,Node to,int weight)
{
this.from=from;
this.to=to;
this.weight=weight;
}
}
class Node
{
public String value;
public Node(String value)
{
this.value=value;
}
public boolean isVisited=false;
}
class EdgeDist{
public Edge edge;
public int dist;
}
class TreeNode
{
public List<Node> parents;
public Node node;
public int dist;
public TreeNode(Node parent,Node node,int dist)
{
if(this.parents==null)
this.parents=new ArrayList<>();
this.parents.add(parent);
this.node=node;
this.dist=dist;
}
}
public class Dijkstra{
public static List<TreeNode> tree;
public static void main(String[] args) throws Exception {
tree=new ArrayList<>();
Node nodeA=new Node("A");
Node nodeB=new Node("B");
Node nodeC=new Node("C");
Node nodeD=new Node("D");
Node nodeE=new Node("E");
Node nodeF=new Node("F");
Edge edgeA_B=new Edge(nodeA,nodeB,1);
Edge edgeA_D=new Edge(nodeA,nodeD,2);
Edge edgeB_C=new Edge(nodeB,nodeC,3);
Edge edgeD_E=new Edge(nodeD,nodeE,3);
Edge edgeC_E=new Edge(nodeC,nodeE,1);
Edge edgeC_F=new Edge(nodeC,nodeF,4);
Edge edgeE_F=new Edge(nodeE,nodeF,1);
List<Edge> edges=new ArrayList<>(Arrays.asList(edgeA_B,edgeA_D,edgeB_C,edgeD_E,edgeC_E,edgeC_F,edgeE_F));
List<Node> nodes=new ArrayList<>(Arrays.asList(nodeA,nodeB,nodeC,nodeD,nodeE,nodeF));
run(nodes,edges);
println();
}
private static void println()
{
TreeNode root=tree.remove(0);
printDist(root,root.node.value,1);
}
private static void printDist(TreeNode curr,String path,int tagCount)
{
if(tagCount==tree.size()) return;
//是否
int finalTagCount = tagCount;
tree.stream().filter(treeNode ->{
Optional<Node> parent= treeNode.parents.stream().filter(p->p.equals(curr.node)).findAny();
if(!parent.isEmpty())
{
parent.get().isVisited=true;
return true;
}
return false;
}) .forEach(sub->{
String pathSub=path+"->"+sub.node.value;
int subDist=sub.dist;
System.out.println(pathSub+": "+subDist);
boolean parentAllVisited=sub.parents==null||sub.parents.stream().allMatch(p->p.isVisited);
final int count= parentAllVisited? finalTagCount +1: finalTagCount;
printDist(sub,pathSub,count);
});
}
private static void run(List<Node> nodes,List<Edge> edges)
{
Node fromNode=nodes.remove(0);
tree.add(new TreeNode(null,fromNode,0));
PriorityQueue<EdgeDist> queue=new PriorityQueue(new Comparator<EdgeDist>(){
@Override
public int compare(EdgeDist c1, EdgeDist c2) {
int compare=c1.dist-c2.dist;
if(compare==0)
{
boolean isInTree1=tree.stream().anyMatch(node->node.node.equals(c1.edge.to));
boolean isInTree2=tree.stream().anyMatch(node->node.node.equals(c2.edge.to));
if(isInTree1&&isInTree2)
throw new RuntimeException("node is in the tree : "+c1.edge.to.value);
return (isInTree1?1:0)-(isInTree2?1:0);
}
return compare;
}
});
do{
addElements(fromNode,edges,queue);
EdgeDist edgeDist=queue.poll();
fromNode=edgeDist.edge.to;
nodes.remove(fromNode);
tree.add(new TreeNode(edgeDist.edge.from,fromNode,edgeDist.dist));
}while (!nodes.isEmpty());
}
private static void addElements(Node fromNode,List<Edge> edges,PriorityQueue<EdgeDist> queue)
{
List<Edge> outEdges=edges.stream().filter(e->e.from.equals(fromNode)).collect(Collectors.toList());
if(outEdges.size()>0)
{
outEdges.forEach(e->{
EdgeDist edgeDist=new EdgeDist();
edgeDist.edge=e;
edgeDist.dist=getCurrentDist(e);
queue.add(edgeDist);
});
}
}
private static int getCurrentDist(Edge edge) {
Node curr=edge.to;
int dist=edge.weight;
Optional<TreeNode> optional=tree.stream().filter(treeNode -> treeNode.node.equals(edge.from)).findFirst();
if(optional.isEmpty())
throw new RuntimeException("no treenode found in tree !" + edge.from.value);
dist+=optional.get().dist;
return dist;
}
}
关于正确性的证明:
网上的归纳法看不下去,把过程又演练了遍。
发现其实很像“触角”,哪里短往哪儿延伸。
这样的画面终于说服了自己,好像关节被打通了,舒畅!
来源:CSDN
作者:干城
链接:https://blog.csdn.net/ff1990723/article/details/104132887