# 程序员必须会的基本算法8-Dijkstra算法(迪杰斯特拉算法)

## 代码解决

package basic;

public class Dijkstra
{
/*
* 看完下面的,我们来总体看下迪杰斯特拉算法的运行策略
* 首先访问过的只有一个G,然后找到G能访问的节点中权重最小的
* 那就是GA,然后将GA看做一个节点,能访问到的节点中权重最小的
* 那就是GAB,然后又看作一个整体,下一个能访问到的节点中权重最小的
* 那就是GABE,就是这样的策略
*/
public static void main(String[] args)
{
//		char[] nodes={ 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
//		int[][] weight=new int[nodes.length][nodes.length];
//		final int N=Integer.MAX_VALUE/2;
//
//		weight[0]=new int[]{N,5,7,N,N,N,2};
//		weight[1]=new int[]{5,N,N,9,N,N,3};
//		weight[2]=new int[]{7,N,N,N,8,N,N};
//		weight[3]=new int[]{N,9,N,N,N,4,N};
//		weight[4]=new int[]{N,N,8,N,N,5,4};
//		weight[5]=new int[]{N,N,N,4,5,N,6};
//		weight[6]=new int[]{2,3,N,N,4,6,N};
//上面都是初始化数据
char[] nodes={ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ,'H','I'};
int[][] weight=new int[nodes.length][nodes.length];
final int N=Integer.MAX_VALUE/2;

weight[0]=new int[]{N,5,7,N,N,N,2,N,N};
weight[1]=new int[]{5,N,N,9,N,N,3,N,N};
weight[2]=new int[]{7,N,N,N,8,N,N,N,N};
weight[3]=new int[]{N,9,N,N,N,4,N,2,N};
weight[4]=new int[]{N,N,8,N,N,5,4,N,N};
weight[5]=new int[]{N,N,N,4,5,N,6,N,N};
weight[6]=new int[]{2,3,N,N,4,6,N,N,N};
weight[7]=new int[]{N,N,N,2,N,N,N,N,2};
weight[8]=new int[]{N,N,N,N,N,N,N,2,N};

dijkstra(weight, 6);
}
public static void dijkstra(int[][] weight,int index)
{
//需要三个额外的变量来保存数据
//这表示这个节点是否是已经被访问过了
int[] vistied=new int[weight.length];
//这表示路径是什么
String[] paths=new String[weight.length];
//这表示从出发点到当前节点的距离是多少
int[] TheLength=new int[weight.length];

//初始化路径
for(int x=0;x<paths.length;x++)
{
paths[x]=new String(index+"->"+x);
}
//初始化出发点
vistied[index]=1;
TheLength[index]=0;
/*
* 然后是遍历n-1个节点,因为第一个节点已经遍历过了
* 这里每一次都是找和出发点相通的,权重最小的那个节点,
* 然后对它进行深一层的遍历,看看它走到下一层后的最小路径是否能更加小
* 在这里你可能在想第二重的for循环会不会没有进去,就是那个找MinLength的for循环
* 然后让下标temp=-1,其实不会的,在后面的for遍历下一层的时候会改变下一层图的遍历
* 就是比如出发点是第零层,然后MinLength是找第二层节点的最小权重,然后下面的for会
* 根据第二层的最小权重去找第二层到第三层的最小权重,如果是出发点不能到达的节点
* 那么就肯定在第三层或者更加低的层,那么在第二层遍历会修改第三层节点的可达,就是修改权重
* 那么循环后再回到上面的寻找下一个最小权重的没有访问过的节点的时候就会可能不是从
* 第二层找起,而是直接到更加低的层次找
*/
for(int x=1;x<weight.length;x++)
{
int MinLength=Integer.MAX_VALUE/2;
int temp=-1;
for(int y=0;y<weight.length;y++)
{
if(vistied[y]==0 && weight[index][y]<MinLength)
{
MinLength=weight[index][y];
temp=y;
}
}
TheLength[temp]=MinLength;
vistied[temp]=1;
/**
* 首先是出发点到index节点的距离,然后index这个节点能访问的下一层节点
* 如果是从index这个节点出发访问到的下一层节点的距离加上从出发点到index的距离
* 比从出发点到index下一层节点的距离(这是不经过index节点的,从其他的路线出发的)小,
* 那么就将这TheLength的数组对应的index下一层节点对应的位置进行修改
*/
for(int y=0;y<weight.length;y++)
{
if(vistied[y]==0 && weight[index][temp]+weight[temp][y]<weight[index][y])
{
weight[index][y]=weight[index][temp]+weight[temp][y];
paths[y]=paths[temp]+"->"+y;
}
}
}
for(int x=0;x<paths.length;x++)
{
if(x!=index)
{
System.out.println(index+"到"+x+"的路径:"+paths[x]+"		权重:"+TheLength[x]);
}
}
}
}


6到0的路径:6->0		权重:2
6到1的路径:6->1		权重:3
6到2的路径:6->0->2		权重:9
6到3的路径:6->5->3		权重:10
6到4的路径:6->4		权重:4
6到5的路径:6->5		权重:6
6到7的路径:6->5->3->7		权重:12
6到8的路径:6->5->3->7->8		权重:14


## 注意

1.迪杰斯特拉算法只支持非负权的图

2.节点之间不可达用Integer.MAX_VALUE代表

• 点赞
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

ReflectMirroring

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文

03-30 11万+
04-23 1481
12-26 167
10-23 138
03-11 2712