算法——数据结构图的最短路径实现JAVA代码

2 篇文章 0 订阅
1 篇文章 0 订阅
图求最短路径的Floyd和Dijkstra算法JAVA代码实现

package graph;

/**
 * Created by Thinkpad on 2014/3/31.
 */
public class VertexType
{
    private String name;
    private int id;

    public VertexType(int i, String a)
    {
        id = i;
        name = a;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }
}
package graph;

/**
 * Created by Thinkpad on 2014/3/31.
 */
public class EdgeType
{
    protected int weight;

    public EdgeType(int weight)
    {
        this.weight = weight;
    }
}

package graph;

import java.util.ArrayList;
import java.util.HashMap;

public class GraphMatrixOperator
{
    private static final int INFINITY = 65535;
    private ArrayList<ArrayList<EdgeType>> arcList = new ArrayList<ArrayList<EdgeType>>();
    private ArrayList<VertexType> vertexes = new ArrayList<VertexType>();
    private HashMap<String, VertexType> vertexNodeHashMap = new HashMap<String, VertexType>();
    //    protected  int[] p;    /* 用于存储最短路径下标的数组 */
//    protected  int[] d ;/* 用于存储到各点最短路径的权值和 */
    private int numVertexes;
    private int numEdges;

    public ArrayList<ArrayList<EdgeType>> getArcList()
    {
        return arcList;
    }


    public ArrayList<VertexType> getVertexes()
    {
        return vertexes;
    }


    public HashMap<String, VertexType> getVertexNodeHashMap()
    {
        return vertexNodeHashMap;
    }


    /* 建立无向网图的邻接矩阵表示 */
    public static void initMGraph(GraphMatrixOperator g)
    {

    }

    protected static void initVertexes(GraphMatrixOperator g)
    {
        for (int i = 0; i < g.numVertexes; i++) /* 读入顶点信息,建立顶点表 */
        {
            g.getVertexes().set(i, new VertexType(i, ""));
        }
    }

    protected static void initArcWithIJ(GraphMatrixOperator g)
    {
        for (int i = 0; i < g.getNumVertexes(); i++)
        {
            for (int j = i; j < g.getNumVertexes(); j++)
            {
                g.getArcList().get(j).get(i).weight = g.getArcList().get(i).get(j).weight;
            }
        }
    }


    protected static void initNet(GraphMatrixOperator g)
    {
        for (int i = 0; i < g.numVertexes; i++)/* 初始化图 */
        {
            for (int j = 0; j < g.numVertexes; j++)
            {
                if (i == j)
                {
                    g.getArcList().get(i).set(j, new EdgeType(0));
                }
                else
                {
                    g.getArcList().get(i).set(j, new EdgeType(INFINITY));
                    g.getArcList().get(j).set(i, new EdgeType(INFINITY));
                }
            }
        }
    }

    private static void initArcList(GraphMatrixOperator g, int size)
    {
        for (int i = 0; i < size; i++)
        {
            ArrayList<EdgeType> al = new ArrayList<EdgeType>();
            g.getArcList().add(al);

            for (int j = 0; j < size; j++)
            {
                if (i == j)
                {
                    al.add(new EdgeType(0));
                }
                else
                {
                    al.add(new EdgeType(INFINITY));
                }
            }
        }
    }

    public static void addArcFromI2J(GraphMatrixOperator g, String a, String b, int w)
    {
        addVex(g, a);
        addVex(g, b);
        g.getArcList().get(g.getVertexNodeHashMap().get(a).getId()).get(g.getVertexNodeHashMap().get(b).getId()).weight = w;
        g.getArcList().get(g.getVertexNodeHashMap().get(b).getId()).get(g.getVertexNodeHashMap().get(a).getId()).weight = w;
    }

    private static void addVex(GraphMatrixOperator g, String a)
    {
        if (!g.getVertexNodeHashMap().containsKey(a))
        {
            int size = g.getVertexes().size();
            VertexType e = new VertexType(size, a);
            g.getVertexes().add(e);
            g.getVertexNodeHashMap().put(a, e);
        }
    }
    /*  Dijkstra算法,求有向网G的v0顶点到其余顶点v的最短路径p[v]及带权长度d[v] */
/*  p[v]的值为前驱顶点下标,d[v]表示v0到v的最短路径长度和 */

    public static void shortestPath_Dijkstra(GraphMatrixOperator g, int v0, int[] p, int[] d)
    {
        int v, w, k = 0, min;
        int maxvex = g.getNumVertexes();
        int[] finalInt = new int[maxvex];/* finalInt[w]=1表示求得顶点v0至vw的最短路径 */
        int n = g.numVertexes;
        for (v = 0; v < n; v++)    /* 初始化数据 */
        {
            finalInt[v] = 0;			/* 全部顶点初始化为未知最短路径状态 */
            d[v] = g.getArcList().get(v0).get(v).weight;/* 将与v0点有连线的顶点加上权值 */
            p[v] = -1;				/* 初始化路径数组P为-1  */
        }

        d[v0] = 0;  /* v0至v0路径为0 */
        finalInt[v0] = 1;    /* v0至v0不需要求路径 */
    /* 开始主循环,每次求得v0到某个v顶点的最短路径 */
        for (v = 1; v < n; v++)
        {
            min = INFINITY;    /* 当前所知离v0顶点的最近距离 */
            for (w = 0; w < n; w++) /* 寻找离v0最近的顶点 */
            {
                if ((finalInt[w] == 0) && (d[w] < min))
                {
                    k = w;
                    min = d[w];    /* w顶点离v0顶点更近 */
                }
            }
            finalInt[k] = 1;    /* 将目前找到的最近的顶点置为1 */
            for (w = 0; w < n; w++) /* 修正当前最短路径及距离 */
            {
            /* 如果经过v顶点的路径比现在这条路径的长度短的话 */
                if ((0 == finalInt[w]) && ((min + g.getArcList().get(k).get(w).weight) < d[w]))
                { /*  说明找到了更短的路径,修改d[w]和p[w] */
                    d[w] = min + g.getArcList().get(k).get(w).weight;  /* 修改当前路径长度 */
                    p[w] = k;
                }
            }
        }
        System.out.println("final[]:");
        for (int i : finalInt)
        {
            System.out.print(i);
        }
        System.out.println();
    }

    public static void main(String[] args)
    {
        /* 求某点到其余各点的最短路径 */
        String[] src = new String[]{"a,b,1", "b,c,2", "a,c,4", "b,d,7"};

        GraphMatrixOperator g = createMGraph(src);

        logMGraph(g);

        int v0 = 0;
        main_Dijkstra(g, v0);
        main_floyd(g);
    }

    private static GraphMatrixOperator createMGraph(String[] src)
    {
        GraphMatrixOperator g = new GraphMatrixOperator();
        initArcList(g, src.length);

        for (String s : src)
        {
            System.out.println(s);
            String[] line = s.split(",");
            addArcFromI2J(g, line[0], line[1], Integer.valueOf(line[2]));
        }
        int size = g.getVertexes().size();
        g.setNumVertexes(size);
        g.setNumEdges(src.length);

        return g;
    }

    private static void logMGraph(GraphMatrixOperator g)
    {
        for (VertexType vertexType : g.getVertexes())
        {
            System.out.print(vertexType.getName() + " ");
        }
        System.out.println();
        for (ArrayList<EdgeType> edgeTypes : g.getArcList())
        {
            for (EdgeType edgeType : edgeTypes)
            {
                System.out.print(edgeType.weight + "  ");
            }
            System.out.println();
        }
    }


    private static void main_Dijkstra(GraphMatrixOperator g, int v0)
    {
        int size = g.getVertexes().size();
        int[] p = new int[size];
        int[] d = new int[size];
        shortestPath_Dijkstra(g, v0, p, d);

        System.out.println("用于存储到各点最短路径的权值和:");
        for (int i : d)
        {
            System.out.print(i + " ");
        }
        System.out.println();
        System.out.println("用于存储最短路径下标的数组 :");
        for (int i : p)
        {
            System.out.print(i + " ");
        }
        System.out.println();


        System.out.println("最短路径倒序如下:");

        int j;
        for (int i = 1; i < g.numVertexes; ++i)
        {
            System.out.print(v0 + "-" + i + ":");
            j = i;
            while (p[j] != -1)
            {
                System.out.print(g.getVertexes().get(p[j]).getName());
                j = p[j];
            }
            System.out.println();
        }

        System.out.println("\n源点到各顶点的最短路径长度为:");
        for (int i = 1; i < g.numVertexes; ++i)
        {
            System.out.print(g.getVertexes().get(v0).getName() + "-");
            System.out.print(g.getVertexes().get(i).getName() + ":");
            System.out.println(d[i]);
        }
    }

    public void setNumVertexes(int numVertexes)
    {
        this.numVertexes = numVertexes;
    }

    public int getNumVertexes()
    {
        return numVertexes;
    }

    public void setNumEdges(int numEdges)
    {
        this.numEdges = numEdges;
    }

    public int getNumEdges()
    {
        return numEdges;
    }

    /* Floyd算法,求网图G中各顶点v到其余顶点w的最短路径p[v][w]及带权长度d[v][w]。 */
    public static void shortestPath_Floyd(GraphMatrixOperator g, int[][] pList, int[][] dList)
    {
        int size = g.numVertexes;
        for (int v = 0; v < size; ++v) /* 初始化D与P */
        {
            for (int w = 0; w < size; ++w)
            {
                dList[v][w] = g.arcList.get(v).get(w).weight;	/* d[v][w]值即为对应点间的权值 */
                pList[v][w] = w;				/* 初始化P */
            }
        }
        for (int k = 0; k < size; ++k)
        {
            for (int v = 0; v < size; ++v)
            {
                for (int w = 0; w < size; ++w)
                {
                    if (dList[v][w] > dList[v][k] + dList[k][w])
                    {/* 如果经过下标为k顶点路径比原两点间路径更短 */
                        dList[v][w] = dList[v][k] + dList[k][w];/* 将当前两点间权值设为更小的一个 */
                        pList[v][w] = pList[v][k];/* 路径设置为经过下标为k的顶点 */
                    }
                }
            }
        }
    }

    public static void main_floyd(GraphMatrixOperator g)
    {
        int size = g.getVertexes().size();
        int[][] pList = new int[size][size];
        int[][] dList = new int[size][size];

        shortestPath_Floyd(g, pList, dList);

        printPath(size, pList, dList);
        printDList(size, dList);
        printPList(size, pList);
    }

    private static void printPList(int size, int[][] pList)
    {
        System.out.println("最短路径的下标P:");
        for (int v = 0; v < size; ++v)
        {
            for (int w = 0; w < size; ++w)
            {
                System.out.print(pList[v][w] + "-");
            }
            System.out.println();
        }
    }

    public static void printDList(int size, int[][] dList)
    {
        System.out.println("最短路径的权值和D:");
        for (int v = 0; v < size; ++v)
        {
            for (int w = 0; w < size; ++w)
            {
                System.out.print(dList[v][w] + "-");
            }
            System.out.println();
        }
    }

    public static void printPath(int size, int[][] pList, int[][] dList)
    {
        System.out.println("各顶点间最短路径如下:");
        for (int v = 0; v < size; ++v)
        {
            for (int w = v + 1; w < size; w++)
            {
                System.out.println(v + "-" + w + ":" + dList[v][w]);
                printPathFromV2W(pList, v, w);
            }
        }
    }

    public static void printPathFromV2W(int[][] pList, int v, int w)
    {
        int k;
        k = pList[v][w];				/* 获得第一个路径顶点下标 */
        System.out.print(v + "-");	/* 打印源点 */
        while (k != w)				/* 如果路径顶点下标不是终点 */
        {
            System.out.print(k + "-");	/* 打印路径顶点 */
            k = pList[k][w];			/* 获得下一个路径顶点下标 */
        }
        System.out.println(w);	/* 打印终点 */
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra算法可以用来求带权有向上的最短路径,下面是Java实现: ```java import java.util.*; public class DijkstraAlgorithm { private static final int MAX = Integer.MAX_VALUE; // 定义无穷大 public static void dijkstra(int[][] graph, int start) { int n = graph.length; // 的大小 int[] dist = new int[n]; // 存储起点到各个点的最短距离 boolean[] visited = new boolean[n]; // 标记各个结点是否已经访问过 int[] prev = new int[n]; // 存储到达各个结点的前驱结点 // 初始化 for (int i = 0; i < n; i++) { dist[i] = MAX; visited[i] = false; prev[i] = -1; } dist[start] = 0; // 循环n-1次,每次确定一个顶点的最短路径 for (int i = 0; i < n - 1; i++) { int minDist = MAX; int u = -1; // 找到当前未访问的结点中距离起点最近的结点 for (int j = 0; j < n; j++) { if (!visited[j] && dist[j] < minDist) { minDist = dist[j]; u = j; } } if (u == -1) { break; } visited[u] = true; // 更新与u相邻的结点的最短距离 for (int j = 0; j < n; j++) { if (!visited[j] && graph[u][j] != MAX) { int newDist = dist[u] + graph[u][j]; if (newDist < dist[j]) { dist[j] = newDist; prev[j] = u; } } } } // 输出结果 System.out.println("起点为" + start + "的最短路径如下:"); for (int i = 0; i < n; i++) { if (i != start && dist[i] != MAX) { System.out.print("从" + start + "到" + i + "的最短路径为:" + start); int j = i; while (j != start) { System.out.print(" -> " + j); j = prev[j]; } System.out.println(",路径长度为:" + dist[i]); } } } public static void main(String[] args) { int[][] graph = { {0, 1, 12, MAX, MAX}, {MAX, 0, 9, 3, MAX}, {MAX, MAX, 0, MAX, 5}, {MAX, MAX, 4, 0, 13}, {MAX, MAX, MAX, MAX, 0} }; dijkstra(graph, 0); } } ``` 运行结果: ``` 起点为0的最短路径如下: 从0到1的最短路径为:0 -> 1,路径长度为:1 从0到2的最短路径为:0 -> 1 -> 3 -> 2,路径长度为:12 从0到3的最短路径为:0 -> 1 -> 3,路径长度为:4 从0到4的最短路径为:0 -> 1 -> 3 -> 2 -> 4,路径长度为:17 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值