迪杰斯特拉算法

1.顶点状态
import java.util.Arrays;

public class visitVertex {
    /*-------------成员变量------------*/
    static int Max = Integer.MAX_VALUE;

    // 记录顶点是否被访问,0:未被访问过,1:已被访问
    public int[] isNo_Visited;
    // 记录前一个顶点的索引
    public int[] pre_vertex;
    // 记录出发顶点到其他顶点的距离
    public int[] dis;

    /*-------------构造方法----------*/
    public visitVertex() {

    }

    /**
     * 初始化数组
     *
     * @param vertex_Num   顶点的数量
     * @param start_vertex 起始顶点的索引
     */
    public visitVertex(int vertex_Num, int start_vertex) {
        // 初始化元素为0
        this.isNo_Visited = new int[vertex_Num];
        this.pre_vertex = new int[vertex_Num];
        this.dis = new int[vertex_Num];

        // 起始顶点到其他顶点的距离初始化为一个无穷大的数
        Arrays.fill(dis, Max);
        // 设置起始顶点已被访问过
        this.isNo_Visited[start_vertex] = 1;
        // 起始顶点到自己的距离设置为0
        this.dis[start_vertex] = 0;
    }

    /*------------------成员方法---------------------*/

    /**
     * 判断顶点是否被访问过 --> 访问过:true,否则:false
     *
     * @param index 顶点的索引
     * @return
     */
    public boolean isNoVisited(int index) {
        return isNo_Visited[index] == 1;
    }

    /**
     * 更新起始顶点到目标顶点的距离
     *
     * @param index    目标顶点的索引
     * @param distance 新的距离
     */
    public void updateDistance(int index, int distance) {
        dis[index] = distance;
    }

    /**
     * 更新索引为v1的顶点的前驱顶点为索引为v2的顶点
     *
     * @param v1 要更新的顶点的索引
     * @param v2 要更新的顶点的前驱顶点的索引
     * @return 新的距离
     */
    public int updatePreVertex(int v1, int v2) {
        return pre_vertex[v1] = v2;
    }

    /**
     * 更新出发顶点到目标顶点的距离
     *
     * @param index 目标顶点的索引
     * @return 新的距离
     */
    public int startVertex_targetVertex(int index) {
        return dis[index];
    }

    /**
     * 计算新的访问顶点的索引
     *
     * @return 下一个访问顶点的索引(广度优先)
     */
    public int newVisit_Vertex() {
        // 新的访问带顶点的索引
        int index = 0;
        for (int i = 0; i < isNo_Visited.length; i++) {
            // 如果没有访问过,并且是上个访问顶点的直达顶点,就返回其索引
            if (!isNoVisited(i) && startVertex_targetVertex(i) < Max) {
                // 更新距离
                Max = startVertex_targetVertex(i);
                // 更新索引
                index = i;
            }
        }
        // 将这个顶点标记为已访问过
        isNo_Visited[index] = 1;
        return index;
    }

    // 显示3个数组
    public void showArr() {
        // isNo_Visited
        for (int i : isNo_Visited) {
            System.out.print(i + "\t");
        }
        System.out.println();
        System.out.println("-------------------------");

        // pre_vertex
        for (int j : pre_vertex) {
            System.out.print(j + "\t");
        }
        System.out.println();
        System.out.println("---------------------------");

        // dis
        for (int k : dis) {
            System.out.print(k + "\t");
        }
    }

    public void show(){
        showArr();
    }
}
2.Dijsktra
import java.util.Arrays;

public class Graph {
    // 成员变量
    private char[] vertex; // 存放顶点的数组
    private int[][] Link_Array; // 邻接矩阵
    private visitVertex v; // 存放顶点状态的数组对象

    // 构造方法
    public Graph() {
    }

    public Graph(char[] vertex, int[][] link_Array) {
        this.vertex = vertex;
        this.Link_Array = link_Array;
    }

    // 成员方法
    // 显示图
    public void showGraph() {
        for (int i = 0; i < vertex.length; i++) {
            for (int j = 0; j < vertex.length; j++) {
                System.out.printf("%12d", Link_Array[i][j]);
            }
            System.out.println();
        }
    }

    // 显示结果
    public void show() {
        v.showArr();
    }


    /**
     * Dijkstra算法
     *
     * @param index 起始顶点的索引
     */
    public void Dijkstra(int index) {
        v = new visitVertex(vertex.length, index);
        updateDistance(index); // 更新指定顶点到周围顶点的距离、周围顶点的前驱顶点
        // 选择新的访问顶点,并返回其索引
        for (int i = 1; i < vertex.length; i++) {
            index = v.newVisit_Vertex();
            updateDistance(index); // 更新指定顶点到周围顶点的距离、周围顶点的前驱顶点
        }
    }

    /**
     * 更新指定顶点到周围顶点的距离、周围顶点的前驱顶点
     *
     * @param index
     */
    public void updateDistance(int index) {
        // 用于更新出发顶点到目标顶点的距离
        int len = 0;
        // 遍历邻接矩阵的第Link_Array[index]行,比较距离,判断是否需要更新
        for (int target = 0; target < Link_Array[index].length; target++) {
            // 计算出发顶点到index顶点+index顶点到目标顶点的距离之和
            len = v.startVertex_targetVertex(index) + Link_Array[index][target];
            // 比较这个距离和邻接矩阵中的距离
            if (!v.isNoVisited(target) && len < v.startVertex_targetVertex(target)) {
                // 更新目标顶点的前驱顶点
                v.updatePreVertex(target, index);
                // 更新出发顶点到目标顶点的距离
                v.updateDistance(target, len);
            }
        }
    }
}
3.入口
public class Input {
    static int Max = Integer.MAX_VALUE; // 当两个顶点不能直达时,设置其权值为无穷大,这里使用int最大值表示

    public static void main(String[] args) {
        // 顶点
        char[] vertex = {'A', 'B', 'C', 'D'};
        // 对应的邻接矩阵
        int[][] Link_Array = {
                {Max, 100, 20, Max},
                {100, Max, 70, 60},
                {20,70,Max,50},
                {Max, 60,50,Max}
        };
        Graph graph = new Graph(vertex, Link_Array);
        graph.showGraph();

        graph.Dijkstra(1);
        graph.show();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值