Dijkstra 算法

 今天又翻了翻算法导论,看了看dijstra算法。兴趣来了就实现了下。完全按照书上的步骤实现,没有使用最小堆等数据结构,使用的邻接表方式表示图。因此实现的算法效率很抵,不过这里只是想通过程序来说明这个算法。不是工程上用的。如果工程上使用,最好用矩阵表示图,然后再使用最小堆。。。。不多说了,直接上代码。

(原理参见算法导论第二版p366)

 

package Graph;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;


public class Dijkstra2 {
	private AdjacencyList adjList = new AdjacencyList();
	public static void main(String[] args) {
		try{
			double[][] matrix = { 
					{ util.max, 5, util.max, util.max, 10 }, 
					{ util.max, util.max, 2, 9, 3 },
					{ 7, util.max, util.max, 6, util.max },
					{ util.max, util.max, 4 , util.max, util.max },
					{ util.max, 2, util.max, 1, util.max } 
					};
			
			Dijkstra2 dijkstra = new Dijkstra2(matrix);
			
			dijkstra.adjList.print();
			dijkstra.calculate(0);
			dijkstra.print();
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
   public Dijkstra2(double [][] matrix){
	   adjList = new AdjacencyList(matrix);
   }
   //存储前驱节点
   private int [] pre ;
   //存储距离
   private double [] dist;
   /**
    * @function 计算最近路径
    * @param v 源点
    */
   public void calculate(int v){
	   pre = new int [this.adjList.size()];
	   dist = new double[this.adjList.size()];
	   //s序列,存放
	   boolean [] s = new boolean [this.adjList.size()];
	   
	   //初始化距离
	   Arrays.fill(dist, util.max);
	   //初始化前驱节点
	   Arrays.fill(pre, -1);
	   //初始队列s中没有点
	   Arrays.fill(s, false);
	   
	   //源点的距离为0
	   dist[v] = 0;
	   int gray = v;
	  
	   while(true){
		   //找出距离最小的点
		   double mindis = Double.MAX_VALUE;
		   for(int i = 0 ; i < dist.length ; i++){
			   if(mindis > dist[i] && !s[i]){
				   mindis = dist[i];
				   gray = i;
			   }
		   }
		   //把找到的这个点加入到s队列中
		   s[gray] = true;
		   
		   //======对与gray点有边的点进行松驰=====
		   Node pnode = adjList.get(gray);
		   //向后移一个节点,因为第一个节点是自己。后面的点才是当前节点的后继节点。
		   pnode = pnode.next;
		   while(pnode != null){
			   //后继节点与当前节点的距离 + 当前节点与源点的距离   < 	后继节点到源点的距离
			   if(pnode.weight + mindis < dist[pnode.index]){
				   //后继节点的到源点的距离 更新 为 后继节点与当前节点的距离 + 当前节点与源点的距离
				   dist[pnode.index] = pnode.weight + mindis;
				   //后继节点的前驱节点更新为 当前节点
				   pre[pnode.index] = adjList.get(gray).index;
			   }
			   //下一个后继节点
			   pnode = pnode.next;
		   }
		   
		   //===判断s中是否包含全部的点了
		   boolean con = false;
		   for(boolean b : s)
			   if(b == false){
				   con = true;
				   break;
			   }
		   if(!con)
			   break;
		   
	   }
	   
   }
	
 
	public void print() {
		for(int i = 0 ; i < dist.length ; i++){
			System.out.print(dist[i] + "\t");
			printpath(i);
			System.out.println();
		}
	}

	public void printpath(int v){
		Stack<Integer> stack = new Stack<Integer>(); 
		while(pre[v] >= 0){
			stack.add(pre[v]);
			v = pre[v];
		}
		while(stack.size() > 0)
			System.out.print(stack.pop() + "\t");
	}
   public double getWeight(Node node , int index){
	   while(node != null){
		   int ndx = node.index;
		   if(ndx == index)
			   return node.weight;
		   node = node.next;
	   }
	   return util.max;
   }
}

class AdjacencyList{
	
	private List<Node> adjList = new ArrayList<Node>();
	public AdjacencyList(){};
	
	public int size(){
		return adjList.size();
	}
	public Node get(int index){
		return this.adjList.get(index);
	}
	public List<Node> getData(){
		return this.adjList;
	}
	public AdjacencyList(double [][] matrix){
		for(int i = 0 ; i < matrix.length ; i++){
			double [] vals = matrix[i];
			addData(i , vals);
		}
	}
	
	public void addData(int v , double [] vals){
		Node  node = new Node(v , 0);
		Node head = node;
		for(int j = 0 ; j < vals.length ; j++){
			if(vals[j] < util.max && vals[j] != 0.0){
				node.next = new Node();
				node = node.next;
				node.set( j , vals[j]);
			}
		}
		adjList.add(head);
	}
	
	public void print(){
		for(Node node : adjList){
			while(node != null){
				System.out.print(node.toString() + "\t");
				node = node.next;
			}
			System.out.println();
		}
	}
}


class Node{
	Node next;
	double weight = util.max;
	int index = -1;
	public Node(){
		
	}
	
	public Node(int index , double weight){
		set(index , weight);
	}
	public void set(int index , double weight){
		this.index = index;
		this.weight = weight;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "[ " + index + " , " + weight + " ]"; 
	}
}

class util{
	public static double max = Double.MAX_VALUE;
}

  

posted on 2016-01-22 10:53  BruceLv  阅读(313)  评论(0编辑  收藏  举报

导航