最短路径(邻接表)-Dijkstra算法

最短路径(邻接表)-Dijkstra算法:生成的图采用邻接表的存储方式。

       具体的实现代码如下:

package com.threeTop.www;

import java.util.Hashtable;
import java.util.Stack;

/**
 * 邻接表存储方式的Dijkstra算法
 * @author wjgs
 *
 */

public class Dijkstra2 {
     
	     //图的顶点数组
		private ListGraphNode []nodes;
		//借助的哈希表
		private Hashtable<Integer,Integer> valueindex=new Hashtable<Integer,Integer>();
		
		/**
		 * 初始化图的顶点
		 * @param vertexes
		 */
		public Dijkstra2(int []vetexes)
		{
			nodes=new ListGraphNode[vetexes.length];
			
			for(int i=0;i<vetexes.length;i++)
			{
				
				//初始化每个节点
				nodes[i]=new ListGraphNode(i,vetexes[i],null);
				//hash记录每个位置
				valueindex.put(vetexes[i], i);
			}
		}
		
		
		/**
		 * 添加start可达到的边
		 * @param start
		 * @param end
		 * @param weights 对应的权值数组
		 */
		public void addEdge(int start ,int []end,int[]weights)
		{
			
			int index=valueindex.get(start);
			if(index<0)
			{
				throw new RuntimeException("未找到指定的起始顶点!");
			}
			ListGraphNode node=nodes[index];
			
			for(int j=0;j<end.length;j++)
			{
				int k=valueindex.get(end[j]);
				
				if(k<0)
				{
					throw new RuntimeException("未找到指定的到达顶点!");
				}
				node.next=new ListGraphNode(k,end[j],weights[j],null);
				node=node.next; //链接下一个
				
			}	
		}
		
		 /**
		  * Dijkstra算法实现到各点的最短路径
		  * @param start
		  */
		 
		 public void dijkstra(int start)
		 {
			 int length =nodes.length;
			 int x=valueindex.get(start);   //记录起始点
			 if(x==-1)
			 {
				 throw new RuntimeException("未找到起始顶点");
			 }
			 
			 //自动初始化为0,都属于未得到最短路径的顶点
			 int[]s=new int[length];
			 //存储v到u的最短距离
			 int [][] distance=new int[length][length];
			 //存储x到u最短路径时u的前一个顶点
			 int []path=new int[length];
			 
			 //初始化path数组
			 for(int i=0;i<length;i++)
			 {
				
					 //初始化path为-1
					 path[i]=-1;
			 }
			 for(int i=0;i<length;i++)
			 {
				 ListGraphNode node=nodes[i];
				 node=node.next;
				 while(node!=null)
				 {
					 distance[i][node.index]=node.weight;
					 
					 if(x==i)
					 {
						 //如果是x顶点的链表,则初始化所有可达顶点的前一个顶点为x
						 path[node.index]=x;
					 }
					 node=node.next;
				 }
				 
			 }
			 
			 //先把起始顶点加入s
			 s[x]=1;
			 
			 for(int i=0;i<length;i++)
			 {
				 //首先需要寻找start顶点到各顶点最短的路径
				 int min=Integer.MAX_VALUE;
				 int v=0;  //记录x到各顶点最短的
				 for(int j=0;j<length;j++)
				 {     //s[j]==1说明已经找到最短路径
					  if(s[j]!=1&&x!=j&&distance[x][j]!=0&&distance[x][j]<min)
					  {
						  min=distance[x][j];
						  v=j;
					  }
				 }
				  //v 是目前x到各顶点最短的
				 s[v]=1;
				 //修正最短路径distance及最短距离path
				 
				 for(int j=0;j<length;j++)
				 {
					 if(s[j]!=1&&distance[v][j]!=0&&(min+distance[v][j]<distance[x][j]||distance[x][j]==0))
					 {
						 //说明加入了中间顶点之后找到了更短的路径
						 distance[x][j]=min+distance[v][j];
						 path[j]=v;
						 
					 }
				 }
				 
			 }
			 
			 //打印最短路径值
			 Stack <Integer>stack=new Stack<Integer>();
			 for(int i=0;i<length;i++)
			 {
				 if(distance[x][i]!=0)
				 {
					 System.out.println(nodes[x].value+"-->"+nodes[i].value+"  最短路径长度:"+distance[x][i]);
					 
					 //path存储路径,可以逆序输出,可以借助栈实现正序输出
					 System.out.print("逆序最短路径输出:");
					 int index=i;
					 while(index!=-1)
					 {
						 System.out.print(nodes[index].value+" ");
						 stack.push(nodes[index].value);
						 index=path[index];
					 }
					 System.out.print("正序最短路径输出:");
					 while(!stack.isEmpty())
					 {
						 System.out.print(stack.pop()+" ");
					 }
					 System.out.println();
				 }
			 }
			
			 
		 }
	public static void main(String[] args) 
	{
		int[] vetexes={1,2,3,4,5,6};
		Dijkstra2 listgraph=new Dijkstra2(vetexes);
		listgraph.addEdge(1, new int[]{2,3,5,6},new int[]{16,1,12,15});
		listgraph.addEdge(2, new int[]{1,4,6},new int[]{16,2,8});
		listgraph.addEdge(3, new int[]{1,5},new int[]{1,5});
		listgraph.addEdge(4, new int[]{2,5,6},new int[]{2,9,3});
		listgraph.addEdge(5, new int[]{1,3,4,6},new int[]{12,5,9,8});
		listgraph.addEdge(6, new int[]{1,2,4,5},new int[]{15,8,3,8});
		listgraph.dijkstra(1);
	}

}

《最短路径(邻接表)-Dijkstra算法》

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/zuochao_2013/article/details/70808810
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞