Dijkstra算法

Dijkstra算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先),直到扩展到终点为止。算法过程太麻烦不写了,直接上代码理解。

import java.util.Arrays;

public class DijkstraAlgorithm {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		char[] verxs = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
		final int INF = 65535;
		int matrix[][] = { { 0, 12, INF, INF, INF, 16, 14 }, { 12, 0, 10, INF, INF, 7, INF },
				{ INF, 10, 0, 3, 5, 6, INF }, { INF, INF, 3, 0, 4, INF, INF }, { INF, INF, 5, 4, 0, 2, 8 },
				{ 16, 7, 6, INF, 2, 0, 9 }, { 14, INF, INF, INF, 8, 9, 0 } };
		Graph graph = new Graph(verxs, matrix);
		graph.dsj(6);
		graph.showDijkstra();

	}

}

class Graph {
	private char[] verxs;// 顶点数组
	private int[][] matrix;// 邻接矩阵
	private VisitedVerxs vv;

	public Graph(char[] verxs, int[][] matrix) {
		this.verxs = verxs;
		this.matrix = matrix;
	}

	public void showDijkstra() {
		vv.show();
	}

	public void showGraph() {
		for (int[] link : matrix) {
			System.out.println(Arrays.toString(link));
		}
	}

	public void dsj(int index) {
		vv = new VisitedVerxs(verxs.length, index);
		update(index);// 更新index顶点到周围顶点的距离和前驱顶点
		for (int j = 0; j < verxs.length; j++) {
			index = vv.updateArr();// 选择并返回新的访问顶点
			update(index);
		}
	}

	// 更新index下标顶点到周围顶点的距离和周围顶点的前驱顶点
	public void update(int index) {
		int len = 0;
		for (int j = 0; j < matrix[index].length; j++) {
			len = vv.getDis(index) + matrix[index][j];// len是出发顶点到index顶点的距离+从index到j顶点的距离的和
			if (!vv.in(j) && len < vv.getDis(j)) {// j没有被访问过,且len小于出发顶点到j顶点的距离
				vv.updatePre(j, index);// 更新j顶点的前驱为index顶点
				vv.updateDis(j, len);// 更新出发顶点到j顶点的距离
			}
		}
	}
}

class VisitedVerxs {
	// 记录各个顶点是否访问过1表示访问过,0表示未访问
	public int[] already_arr;
	// 每个下标对应的值为前一个顶点下标
	public int[] pre_visited;
	// 记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其他顶点的距离,秋的最短距离存放到dis
	public int[] dis;

	public VisitedVerxs(int length, int index) {
		this.already_arr = new int[length];// length为顶点个数
		this.pre_visited = new int[length];
		this.dis = new int[length];
		// 初始化dis
		Arrays.fill(dis, 65535);
		this.already_arr[index] = 1;// 设置出发顶点被访问过
		this.dis[index] = 0;// index为出发顶点对应下标,设置出发顶点的访问距离为0

	}

	// 判断index是否被访问过,访问过为true
	public boolean in(int index) {
		return already_arr[index] == 1;
	}

	// 更新出发顶点到index顶点的距离
	public void updateDis(int index, int len) {
		dis[index] = len;
	}

	// 更新顶点前驱为index节点
	public void updatePre(int pre, int index) {
		pre_visited[pre] = index;
	}

	// 返回出发顶点到index顶点的距离
	public int getDis(int index) {
		return dis[index];
	}

	// 继续选择并返回新的访问顶点,比如G完后,就是A作为新的访问顶点
	public int updateArr() {
		int min = 65535, index = 0;
		for (int i = 0; i < already_arr.length; i++) {
			if (already_arr[i] == 0 && dis[i] < min) {
				min = dis[i];
				index = i;
			}
		}
		// 更新index被放问过
		already_arr[index] = 1;
		return index;
	}

	// 显示最后的结果,将三个数组的情况输出
	public void show() {
		for (int i : already_arr) {
			System.out.print(i + " ");
		}
		System.out.println();
		for (int i : pre_visited) {
			System.out.print(i + " ");
		}
		System.out.println();
		for (int i : dis) {
			System.out.print(i + " ");
		}
		System.out.println();
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值