package b;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Graph {
private int[][] array;
private Map<Integer,String> xyToName = new HashMap<>();
private Map<String,Integer> nameToXy = new HashMap<>();
private int len;
public void setNode(String[] nodes){
len = nodes.length;
array = new int[len][len];
for(int i=0; i<len; i++){
xyToName.put(i, nodes[i]);
nameToXy.put(nodes[i], i);
for(int j=0; j<len; j++){
if(j == i){
array[i][j] = 0;
}else{
array[i][j] = Integer.MAX_VALUE;
}
}
}
}
public void setPath(String node1, String node2, int weight){
int node1Xy = nameToXy.get(node1);
int node2Xy = nameToXy.get(node2);
array[node1Xy][node2Xy] = weight;
array[node2Xy][node1Xy] = weight;
}
public void createExample(){
this.setNode(new String[]{"A","B","C","D","E","F","G"});
this.setPath("A", "B", 7);
this.setPath("C", "B", 8);
this.setPath("A", "D", 5);
this.setPath("D", "B", 9);
this.setPath("E", "B", 7);
this.setPath("E", "C", 5);
this.setPath("D", "E", 15);
this.setPath("D", "F", 6);
this.setPath("F", "E", 8);
this.setPath("F", "G", 11);
this.setPath("E", "G", 9);
}
public void printArray(){
for(int i=0; i<len; i++){
for(int j=0; j<len; j++){
if(array[i][j] < Integer.MAX_VALUE){
int l = 10 - (array[i][j]+"").length();
while(l > 0){
System.out.print(" ");
l--;
}
}
System.out.print(array[i][j]+", ");
}
System.out.println();
}
}
public void dijkstra(String node){
int nodexy = nameToXy.get(node);
int[] minLen = new int[len];
int[] visite = new int[len];//表示是否访问过,0没有,1访问过
Map<Integer,String> path = new HashMap<>();
visite[nodexy] = 1;
for(int i=0; i<len; i++){
minLen[i] = array[nodexy][i];
path.put(i, node+"->"+xyToName.get(i));
}
int cur = nodexy;
for(int w=0; w<len; w++){
int minPath = Integer.MAX_VALUE;
//寻找没有访问的,距离源节点最近的
for(int e=0; e<len; e++){
if(visite[e] == 0 && minLen[e] < minPath){
cur = e;
minPath = minLen[e];
}
}
//访问此节点
visite[cur] = 1;
for(int k=0; k<len; k++){
if(visite[k] == 0 //未访问过的
&& minLen[cur] != Integer.MAX_VALUE
&& array[cur][k] != Integer.MAX_VALUE
&& minLen[k] > (minLen[cur]+array[cur][k])){
minLen[k] = minLen[cur]+array[cur][k];
path.put(k, path.get(cur)+" / "+xyToName.get(cur)+"->"+xyToName.get(k));
}
}
}
System.out.println("---------");
for(int i=0; i<len; i++){
System.out.println(node+"->"+xyToName.get(i)+" 最小:"+minLen[i]+" 路径:"+path.get(i));
}
}
public void prim(String node){
System.out.println();
System.out.println("最小生成树 prim from: "+node);
int nodexy = nameToXy.get(node);
int[] visite = new int[len];// 0,0,0,1,0,0,0
visite[nodexy] = 1;
//int[] notVisited = new int[len];// 0,0,0,1,0,0,0
//notVisited[nodexy] = 1;
int sum = len - 1;
for(int s=0; s<sum; s++){
int min = Integer.MAX_VALUE;
int selectedX = -1;
int selectedY = -1;
for(int i=0; i < len; i++){
if(visite[i] == 0){
for(int j=0; j < len; j++){
if(visite[j] == 1 && array[i][j] < min){
min = array[i][j];
selectedX = i;
selectedY = j;
}
}
}
}
System.out.println(xyToName.get(selectedY) +"->"+ xyToName.get(selectedX));
visite[selectedX] = 1;
}
}
public static void main(String[] args) {
Graph g = new Graph();
g.createExample();
g.printArray();
g.dijkstra("A");
g.dijkstra("G");
g.prim("D");
}
}
0, 7, 2147483647, 5, 2147483647, 2147483647, 2147483647,
7, 0, 8, 9, 7, 2147483647, 2147483647,
2147483647, 8, 0, 2147483647, 5, 2147483647, 2147483647,
5, 9, 2147483647, 0, 15, 6, 2147483647,
2147483647, 7, 5, 15, 0, 8, 9,
2147483647, 2147483647, 2147483647, 6, 8, 0, 11,
2147483647, 2147483647, 2147483647, 2147483647, 9, 11, 0,
---------
A->A 最小:0 路径:A->A
A->B 最小:7 路径:A->B
A->C 最小:15 路径:A->B / B->C
A->D 最小:5 路径:A->D
A->E 最小:14 路径:A->B / B->E
A->F 最小:11 路径:A->D / D->F
A->G 最小:22 路径:A->D / D->F / F->G
---------
G->A 最小:22 路径:G->F / F->D / D->A
G->B 最小:16 路径:G->E / E->B
G->C 最小:14 路径:G->E / E->C
G->D 最小:17 路径:G->F / F->D
G->E 最小:9 路径:G->E
G->F 最小:11 路径:G->F
G->G 最小:0 路径:G->G
最小生成树 prim from: D
D->A
D->F
A->B
B->E
E->C
E->G