迪杰斯特拉(Dijkstra)

迪杰斯特拉算法主要是用广度优先搜索的算法计算出一个顶点V到各个顶点的最短距离
ver表示没有走过的顶点,dis表示顶点V到各个顶点的距离
首先从ver集合取出取出顶点M,将顶点V的相邻顶点之间的边取出,存储在一个list1集合里面,将其排序
从list1集合取出最小值的顶点N,并查看VM加上MN的距离是否小于VN的距离,小于则更新,并且从未走的集合中删除顶点N

public class DijkstraTest {
    public static void main(String[] args) {
        int INF = Integer.MAX_VALUE;
        char[] vertexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int[][] edges = {
                {0,   12,   INF,  INF,  INF,  16, 14  },
                {12,  0,    10,   INF,  INF,  7,  INF },
                {INF, 10,   0,    3,    5,    6,  INF },
                {INF, INF,  3,    0,    4,    INF,INF },
                {INF, INF,  5,    4,    0,    2,  8   },
                {16,  7,    6,    INF,  2,    0,  9   },
                {14,  INF,  INF,  INF,  8,    9,  0   },
        };
        Dijkstra dijkstra = new Dijkstra(vertexs,edges);
        dijkstra.getMinTrace('C');
        dijkstra.showMinTrace();
    }
}
class Dijkstra{
    private char[] vertexs;  //顶点集合
    private int[] dist; //目标点到各个点的最短距离
    private int[][] edges; //邻接矩阵   
    private ArrayList<MData> firstList; //因为迪杰斯特拉采用广度优先搜索遍历,所以这个存放第一层需要遍历的点的信息
    private ArrayList<MData> secondList; //在将firstList中取出一个点查看他的邻接点的时候,会查看我们的出发点到当前顶点的距离是否小于出发点到该顶点邻接点的最小距离,如果是,则加入secondList集合,并且更新出发点到该邻接点的最小距离
    private HashSet<Character> choice; //没有走过的顶点
    private static final int INF = Integer.MAX_VALUE;
    private HashMap<Character,Integer> vertexToIndex; //将字符转换成其索引,为了方便
    private int startIndex; //出发点在顶点中的索引

    public Dijkstra(char[] vertexs, int[][] edges) { //初始化工作
        this.vertexs = vertexs;
        this.edges = edges;
        vertexToIndex = new HashMap<>();
        choice = new HashSet<>();
        for (int i = 0; i < vertexs.length; i++) {
            vertexToIndex.put(vertexs[i],i);
            choice.add(vertexs[i]);
        }
        firstList = new ArrayList();
    }
    public void getMinTrace(char start){ //基本上也是初始化工作
        startIndex = vertexToIndex.get(start);
        dist = new int[vertexs.length];
        for (int i = 0; i < dist.length; i++) { //首先将出发点到各个顶点的距离设置未无穷大
            dist[i] = INF;
        }
        firstList.add(new MData(start,0)); // 首先加入出发点,便于后面遍历
        dist[startIndex] = 0; //设置自身距离为0
        choice.remove(start); //将出发点从没有走过的顶点里面进行删除
        getMinTrace(); //调用核心算法
    }
    public void getMinTrace(){
        while (!choice.isEmpty()){ //还有点没有走完就继续
            secondList = new ArrayList(); //每一轮都需要从新new一下
            while (!firstList.isEmpty()){ //进行这一层的遍历,因为这里面遍历需要从小打到的遍历,不然就可以直接将firstList与secondList合并为一个了
                MData temp = firstList.remove(0); // 取出删除
                int tempIndex = vertexToIndex.get(temp.next); //获取 当前点的索引
                for (int i = 0; i < edges.length; i++) { //遍历该顶点的邻接点了
                    //temp.weight表示当前遍历点到中心点的最小距离,edges[tempIndex][i]表示改变里点到邻接点的距离,dist[i]表示在这之前中心点到该邻接点的最小距离
                    if(temp.weight + edges[tempIndex][i] < dist[i] && temp.weight + edges[tempIndex][i] > 0){
                        dist[i] = temp.weight + edges[tempIndex][i];
                        secondList.add(new MData(vertexs[i],dist[i]));
                        choice.remove(vertexs[i]);
                    }
                }
            }
            Collections.sort(secondList); //取出来的时候需要从小到大取出,所以需要先进性排序
            firstList = secondList; //赋值进行下一轮遍历
        }
    }
    public void showMinTrace(){
        System.out.println(Arrays.toString(dist));
    }
}
class MData implements Comparable<MData> {
    public char next; //需要从这个点去探索邻接点
    public int weight; //当前(在每一轮循环中)出发点到这个点的最小距离

    public MData(char next, int weight) {
        this.next = next;
        this.weight = weight;
    }

    public int compareTo(MData o) {
        return weight - o.weight;
    }

    @Override
    public String toString() {
        return "MData{next=" + next + ", weight=" + weight + '}';
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容