Java实现dijkstra算法

该代码示例展示了一个用Java编写的类`Tu`,它使用邻接链表存储图,并实现了Dijkstra算法来查找图中的最短路径。类中包含添加节点、建立边以及查找最短路径的方法。测试用例创建了一个五节点的图并找到了从节点0到节点4的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这期代码是查找图中的最短路径,方法改自dijkstra算法,具体总类如下代码:

图采用邻接链表存储。

import java.util.ArrayList;


public class Tu {
	ArrayList<Dian> fi = new ArrayList();//保存图的节点
	//顺序表
	private int length;//保存线性表长度;
	public boolean is_visible = true;
	
	public Tu(){
	}
	/********************内部类***********************/
	private class Tujiedian {
		public Object t;//数据
		
		public int no; //临接点的编号
		
		public int var; //边的权值
		
		public Tujiedian next;//临接节点
		
		public Tujiedian(){	
			this.var = 1;
		}
		public Tujiedian(Object t,int var,Tujiedian next){
			this.t = t;
			this.var = var;
			this.next = next;
		}
	}
//保存在线性表中的节点	
	private class Dian{
		
		public boolean is;//读取标记
		
		public String name;
		
		public Tujiedian m;//邻接链表
		
		public Dian(){
			this.is = false;
		}
		
		public Dian(String name,Tujiedian m){
			this.name = name;
			this.m = m;
			this.is = false;
		}
	
	}	
	/********************内部类***********************/

	private boolean check(int p){
		if(p< 0||p> fi.size()-1){
			return false;
		}else
		    return true;
	}
	//添加点
	public void addV(String name){
		Dian d = new Dian();
		d.name = name;
	//	s.add(d);
		fi.add(d);
	}

	public void set_side(int var,int s1,int s2){
		if(!(check(s1) && check(s2))){
			System.out.println("建立连接失败!");
			return;
		}
		Tujiedian p = fi.get(s1).m;
		Tujiedian n = fi.get(s2).m;
	
		Tujiedian a = new Tujiedian();
		Tujiedian b = new Tujiedian();
		a.no = s2;
		b.no = s1;
		a.var = var;
		b.var = var;
		
			if(p == null){
				fi.get(s1).m = a;
			}else{
				while(p.next != null){
					p=p.next;
				}
				p.next = a;
			}
			if(n == null){
				fi.get(s2).m = b;
			}else{
				while(n.next != null){
					n=n.next;
				}
				n.next = b;
			}
			if(this.is_visible){
				System.out.println("建立连接成功!");
			}
	}
	//查找最短路径:(dijkstra算法)
	public void sert(int t,boolean f){
		this.length = fi.size();
		int k = 114514;//充当正无穷
		boolean[] is_read = new boolean[this.length];
		int[] dis = new int[this.length];
		int[] fv = new int[this.length];
		//将所有的距离都置成正无穷
		for(int i = 0;i<this.length;i++ ){
			dis[i] = k;
		}
		dis[0] = 0;
		fv[0] = -1;//
		
		int v = 0;//标记当前点;
		while(isok(is_read)){//这里的循环控制需要写其他方法
			is_read[v] = true;
			Tujiedian p = fi.get(v).m;
		
			//更新节点信息	
			while(p != null){
				int swap_v = p.no;
				int var = p.var;
				if(dis[v] + var < dis[swap_v]){
					dis[swap_v] = dis[v] + var;//修正距离					
					fv[swap_v] = v;//修正父节点
				}
				p = p.next;
			}		
			//寻找最小距离点			
			int temp = -1;
			for(int i = 0;i< this.length;i++){
				if(!is_read[i]){
					temp = dis[i];
					break;
				}
			}
			
			for(int i = 0;i< this.length;i++){
				if(!is_read[i]){
					if(dis[i] < temp){
						temp = dis[i];
					}
				}
			}
			
			if(temp != -1){
				for(int i = 0;i< this.length;i++){
					if(!is_read[i]){
						if(dis[i] == temp){
							v = i;//节点变更;
							break;
						}
					}					
				}				
			}		  
		}
		//输出最短路径
		print_road(dis,fv,t);
		System.out.println();
		System.out.println("最短距离是:");
		System.out.println(dis[t]);
		
		
		if(f){			
			System.out.println("--------------------------");
			for(int i = 0;i< dis.length;i++){
				System.out.print(i +"  ");
			}
			System.out.println();
			for(int i = 0;i< dis.length;i++){
				System.out.print(dis[i] +"  ");
			}
			System.out.println();
			for(int i = 0;i< dis.length;i++){
				System.out.print(fv[i] +"  ");
			}
		}
	}
	/*
	 * 打印邻接链表;
	 */	
	public void print(){
		System.out.println("图节点"+"\t"+"临接链表");
		for(int i = 0;i< this.length;i++){
			System.out.print(i+"->");
			Tujiedian p = fi.get(i).m;
			while(p != null){
				System.out.print("\t");
				System.out.print(p.no);	
				p = p.next;
			}
			System.out.println();
		}
	}
	//控制循环进程
	
	private boolean isok(boolean[] f){
		boolean t = false;
		
		for(int i = 0;i< this.length;i++){
			
			if(f[i] == false){
				t = true;
				break;
			}
		}
		return t;
	}
	
	private void print_road(int[]dis,int[] fv,int t){
		ArrayList<Integer> a = new ArrayList();//保存路径点
		a.add(t);//添加终点
		int v = t;
		while(v != 0){
			v = find(dis,fv,v);//找出下一个点;
			
			a.add(v);
		}
		System.out.println("最短路径是:");
	
		for(int i = a.size()-1; i>= 0;i--){
			if(i == a.size()-1){
				System.out.print(a.get(i));
			}else{
				
				System.out.print("  ->"+a.get(i));
			}
		}	
	}
	
	private int find(int[]dis,int[] fv,int v){
		int c = -1;
		for(int i = 0;i<this.length;i++){
			if(i == v){
				c = fv[i];
			}
		}
		return c;
	}
}

测试如下:

public class Text {

	public static void main(String[] args){
		// TODO Auto-generated method stub	
		Tu t = new Tu();
		
		t.is_visible = false;
		
		t.addV("0");
		t.addV("1"); 
		t.addV("2");
		t.addV("3");
		t.addV("4");
		
		
		t.set_side(5, 0, 1);
		t.set_side(6, 0, 2);
		t.set_side(10, 2, 1);
		t.set_side(7, 2, 3);
		t.set_side(11, 2, 4);
		t.set_side(4, 1, 4);
		t.set_side(8, 3, 4);
		t.set_side(9, 1, 3);
		
		
		//t.print();
		
		t.sert(4,true);	
		
	}
}

运行结果:

 

 如有错误请指正。

Dijkstra算法是用于解决单源最短路径问题的一种高效算法,特别是在有向无环图(DAG)或带权重的边的图中。在Java实现Dijkstra算法,你可以使用优先队列(通常使用`java.util.PriorityQueue`)来存储尚未确定最短路径的节点,以及一个哈希映射或邻接表来存储图的结构。 以下是Java实现Dijkstra算法的一个基本步骤: 1. 初始化:创建一个HashMap或类似的数据结构,将起点的距离设为0,其他所有节点的距离设为无穷大,同时标记为未访问。 2. 创建优先队列:将起点放入队列,并设置其优先级为起点距离。 3. 主循环:从队列中取出当前距离最小的节点(通常是最小优先级的节点),然后更新其相邻节点的距离,如果通过当前节点到达更短,就更新这些节点的距离并将它们加入队列。 4. 遍历邻接节点:对于每个相邻节点,检查通过当前节点到达它的路径是否比之前记录的更短。如果是,更新并标记该节点为已访问。 5. 重复步骤3和4,直到队列为空或找到终点。如果队列为空且未访问到终点,说明找不到从起点到终点的路径。 ```java import java.util.*; class Node implements Comparable<Node> { int id; int distance; Node previous; public Node(int id) { this.id = id; this.distance = Integer.MAX_VALUE; } @Override public int compareTo(Node other) { return Integer.compare(this.distance, other.distance); } } public class Dijkstra { // 使用PriorityQueue存储节点 private PriorityQueue<Node> queue = new PriorityQueue<>(); // 图的邻接表或哈希映射 private Map<Integer, List<Node>> graph; public List<Node> dijkstra(int start) { // ... (初始化、添加起点到队列等) while (!queue.isEmpty()) { Node current = queue.poll(); // 取出距离最小的节点 // 更新未访问的邻居 for (Node neighbor : graph.get(current.id)) { int distanceToNeighbor = current.distance + neighbor.distance; if (distanceToNeighbor < neighbor.distance) { neighbor.distance = distanceToNeighbor; neighbor.previous = current; queue.offer(neighbor); } } } // 返回从起点到终点的路径,如果找到 return buildPath(start); } private List<Node> buildPath(int end) { List<Node> path = new ArrayList<>(); Node currentNode = endNode(end); while (currentNode != null) { path.add(currentNode); currentNode = currentNode.previous; } Collections.reverse(path); return path; } // ... (获取结束节点的方法,可能需要一个额外的哈希映射存储每个节点的结束标识) } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值