最短路径问题 java实现

Dijkstra 算法: 适用于没有负权边的图,它以贪心的方式逐步确定从起始顶点到其他顶点的最短路径。算法的核心思想是每次选择当前最短路径的顶点,更新其相邻顶点的最短路径。

这是一个实现Dijkstra算法的Java程序,用于求有向图的最短路径。

  1. 类说明:

    • DirectNet1<T>:表示有向图类。
    • LocateVex(T v):在图中查找顶点v的位置。
    • Dijkstra(int v0):实现Dijkstra算法,计算源点v0到其余顶点的最短路径。
    • DisplayPath(int v0):输出源点v0到其余顶点的最短路径和路径长度。
    • CreateAdj():根据用户输入创建图的邻接矩阵。
  2. 成员变量:

    • V:顶点数组。
    • arcs:邻接矩阵,表示各个顶点之间的边的权值。
    • e:图的边数。
    • n:图的顶点数。
    • path[]:保存最短路径上的前驱顶点。
    • dist[]:保存源点到各顶点的最短路径长度。
  3. 主要方法解释:

    • Dijkstra(int v0):该方法使用Dijkstra算法计算从源点v0到其余顶点的最短路径。它使用了一个boolean数组s来标记顶点是否在集合S中,dist数组记录源点到各顶点的最短路径长度,path数组保存最短路径上的前驱顶点。
    • DisplayPath(int v0):该方法输出源点v0到其余顶点的最短路径和路径长度。
  4. CreateAdj() 方法:

    • 用户通过控制台输入图的顶点数、边数、顶点信息以及边的权值。
    • 使用邻接矩阵表示有向图,arcs[i][j]表示顶点i到顶点j的边的权值。
  5. Main 方法:

    • 创建DirectNet1对象。
    • 调用CreateAdj()方法创建有向图。
    • 调用Dijkstra(0)计算从第一个顶点到其余顶点的最短路径。
    • 调用DisplayPath(0)输出最短路径和路径长度。

代码如下:

public class DirectNet1 <T>{
    protected final int MAXSIZE=10;
    protected final int MAX=999;
    protected T[] V;
    protected int[][] arcs;
    protected int e;
    protected int n;

    int path[];
    int dist[];

    public DirectNet1(){
        V=(T[])new Object[MAXSIZE];
        arcs=new int[MAXSIZE][MAXSIZE];
        path=new int[MAXSIZE];
        dist=new int[MAXSIZE];
    }

    public int LocateVex(T v){
        int i;
        for(i=0;i<n;i++){
            if(V[i]==v){
                return i;
            }
        }
        return -1;
    }

    //求有向图G的v0顶点到其余顶点v的最短路径
    public void Dijkstra(int v0){
        int i,j,v=0,w=0;
        int min;
        boolean[] s=new boolean[MAXSIZE];
        for(i=0;i<n;i++){//初始化s,dist和path
            s[i]=false;
            dist[i]=arcs[v0][i];
            if(dist[i]<MAX)path[i]=v0;
            else path[i]=-1;
        }
        dist[v0]=0;s[v0]=true;//初始时源点v0属于s集
        //循环求v0到某个顶点v的最短路径,并将v加入s集
        for(i=1;i<n-1;i++){
            min= MAX;
            for(w=0;w<n;w++){
                //顶点w不属于s集,且离v0更近
                if(!s[w]&&dist[w]<min){
                    v=w;min=dist[w];
                }
            }
            s[v]=true;//顶点v并入s
            for(j=0;j<n;j++){//更新当前最短路径及距离
                if(!s[j]&&(min+arcs[v][j]<dist[j])){
                    dist[j]=min+arcs[v][j];
                    path[j]=v;
                }
            }
        }
    }

    //输出源点v0到其余顶点的最短路径和路径长度
    public void DisplayPath(int v0){
        int i,next;
        for(i=0;i<n;i++){
            if(dist[i]< MAX &&i!=v0){
                System.out.print("V"+i+"<--");
                next=path[i];
                while(next!=v0){
                    System.out.print("V"+next+"<--");
                    next=path[next];
                }
                System.out.println("V"+v0+":"+dist[i]);
            }
            else
            if(i!=v0)
                System.out.println("V"+i+"<--V"+v0+":no path");
        }
    }

    public void CreateAdj() {
        int i, j, k;
        T v1, v2;
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入图的顶点数和边数:");
        System.out.println("顶点数 n = ");
        n = sc.nextInt();

        System.out.println("边数 e = ");
        e = sc.nextInt();

        System.out.println("请输入图的顶点信息:");
        String str = sc.next();
        for (i = 0; i < n; i++) {
            V[i] = (T)(Object)str.charAt(i);
        }

        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                arcs[i][j] = MAX;
            }
        }

        System.out.println("请输入图的边信息:");
        for (k = 0; k < e; k++) {
            System.out.println("请输入第" + (k + 1) + "条边的两个顶点和权值:");
            v1 = (T)(Object)sc.next().charAt(0);
            v2 = (T)(Object)sc.next().charAt(0);
            int weight = sc.nextInt();  // 获取输入的权值
            i = LocateVex(v1);
            j = LocateVex(v2);
            if (i >= 0 && j >= 0) {
                arcs[i][j] = weight;
                arcs[j][i] = weight;  // 如果需要无向图,保留这句
            } else {
                System.out.println("输入的顶点信息不合法,请重新输入。");
                k--; // 使得循环变量 k 不增加,重新输入当前边
            }

        }
    }

    public static void main(String[] args) {
        DirectNet1<Character> G=new DirectNet1<Character>();
        G.CreateAdj();
        G.Dijkstra(0);
        G.DisplayPath(0);
    }

}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值