9、补充视频

改进后的dijkstra算法

利用小根堆
9、补充视频_第1张图片
将小根堆特定位置更改,再改成小根堆
9、补充视频_第2张图片

nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);

9、补充视频_第3张图片

//改进后的dijkstra算法
//从head出发,所有head能到达的节点,生成到达每个节点的最小路径记录并返回
public static HashMap<Node, Integer> dijkstra2(Node head, int size) {
   
	NodeHeap nodeHeap = new NodeHeap(size);
	nodeHeap.addOrUpdateOrIgnore(head, 0);//如果有一个结点的记录是第一次出现,要记录下来,小于update,大于ignore
	HashMap<Node, Integer> result = new HashMap<>();
	while (!nodeHeap.isEmpty()) {
   
		NodeRecord record = nodeHeap.pop();//record:head到node的最短距离
		Node cur = record.node;
		int distance = record.distance;
		for (Edge edge : cur.edges) {
   
			nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);//见图3
		}
		result.put(cur, distance);
	}
	return result;
}

public static class NodeRecord {
   
		public Node node;
		public int distance;

		public NodeRecord(Node node, int distance) {
   
			this.node = node;
			this.distance = distance;
		}
	}

public static class NodeHeap {
   
	private Node[] nodes;
	private HashMap<Node, Integer> heapIndexMap;//记录node在哪个位置上
	private HashMap<Node, Integer> distanceMap;//node到head的最短距离
	private int size;//堆上一共有多少个结点

	public NodeHeap(int size) {
   
		nodes = new Node[size];
		heapIndexMap = new HashMap<>();
		distanceMap = new HashMap<>();
		this.size = 0;
	}

	public boolean isEmpty() {
   
		return size == 0;
	}

	public void addOrUpdateOrIgnore(Node node, int distance) {
   
		if (inHeap(node)) {
   //在堆里
			distanceMap.put(node, Math.min(distanceMap.get(node), distance));//之前的距离和现在的距离用小的
			insertHeapify(node, heapIndexMap.get(node));//向上堆化,根据distanceMap决定一个值上下
		}
		if (!isEntered(node)) {
   //没有进过
			nodes[size] = node;
			heapIndexMap.put(node, size);
			distanceMap.put(node, distance);
			insertHeapify(node, size++);//向上调整
		}
		//进来过没在堆里,ignore
	}

	public NodeRecord pop() {
   
		NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(nodes[

你可能感兴趣的:(左神算法,算法)