My_Graph2 DFS BFS

package interview.src;

import java.util.PriorityQueue;

public class My_Graph_2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//1.Dijstra算法:计算一个节点到其他所有节点的最短路径
		String[] nodes = new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" };  
		My_Graph_2 grf = new My_Graph_2(nodes.length, nodes);  
        grf.initGrf();  
        
//        grf.printMatrix();  
//  
//        System.out.println("Dijkstra迭代 ---");  
//        grf.dijkstra(0);  //起点是 0 
//        grf.printDis();  
//  
//        System.out.println();  
//        System.out.println("Dijkstra优先队列 ---");  
//        grf.dijkstraPQ();  
//        grf.printDis();  

//2.floyd最短路径,图中各个顶点间的最短路径
        int[][] path = new int[nodes.length][grf.matirx.length];
        int[][] floy = new int[nodes.length][grf.matirx.length];
        // floyd算法获取各个顶点之间的最短距离
        grf.floyd(path, floy);
	}
	
	
//1.Dijstra算法:计算一个节点到其他所有节点的最短路径	
	// 为了矩阵的输出更直观好看一些,本例中约定,路径权值取值范围为:[1,10],权值为999表示无连通  
    // 并假设所有权值的和小于999  
    private final int MAX = 999;  
    private int total;       // 顶点总数  
    private String[] nodes;  // 顶点信息  
    private int[][] matirx;  // 顶点矩阵  
    private int[] dis;       // 源点到各顶点的距离  
    private boolean[] visited;      // 顶点是否已标记  
  
    public My_Graph_2(int total, String[] nodes) {  
        this.total = total;  
        this.nodes = nodes;  
        this.matirx = new int[total][total];  
        this.dis = new int[total];  
        this.visited = new boolean[total];  
    }  
  
    // 初始化图数据  
    // 0---1---2---3---4---5---6---7---8---  
    // A---B---C---D---E---F---G---H---I---  
    private void initGrf() {  
        for (int i = 0; i < this.total; i++) {  
            for (int j = 0; j < this.total; j++) {  
                if (i == j) {  
                    this.matirx[i][j] = 0;  
                } else {  
                    this.matirx[i][j] = MAX;  
                }  
            }  
        }  
        
        /**
		---0 1 2 3 4 5 6 7 8
		---A B C D E F G H I
		-A|0 2 m 1 3 m m m m   0
		-B|m 0 2 m m m m m m   1
		-C|m m 0 m m 1 m m m   2
		-D|m m m 0 5 m 2 m m   3
		-E|m m m m 0 6 m 1 m   4 
		-F|m m m m m 0 m m 3   5 
		-G|m m m m m m 0 4 m   6
		-H|m m m m m 1 m 0 2   7 
		-I|m m m m m m m m 0   8
		  **/
        // 手动设置有向路径  
        // A->B, A->E, A->D  
        this.matirx[0][1] = 2;  
        this.matirx[0][4] = 3;  
        this.matirx[0][3] = 1;  
        // B->C  
        this.matirx[1][2] = 2;  
        // C->F  
        this.matirx[2][5] = 1;  
        // D->E, D->G  
        this.matirx[3][4] = 5;  
        this.matirx[3][6] = 2;  
        // E->F, E->H  
        this.matirx[4][5] = 6;  
        this.matirx[4][7] = 1;  
        // F->I  
        this.matirx[5][8] = 3;  
        // G->H  
        this.matirx[6][7] = 4;  
        // H->F, H->I  
        this.matirx[7][5] = 1;  
        this.matirx[7][8] = 2;  
    } 
    
    private void printMatrix() {  
        for (int i = 0; i < this.total; i++) {  
            System.out.print("-" + this.nodes[i] + "|");  
            for (int j = 0; j < this.total; j++) {  
                System.out.print(String.format("%s", this.matirx[i][j]==999?"m":this.matirx[i][j]) + " ");  
            }  
            System.out.println();
        }  
    }  
  
    /** 
     * Dijkstra算法-(迪杰斯特拉)算法之迭代实现 
     *  
     * @param s 源点(起点) 
     */  
    public void dijkstra(int s) {  
        // 初始化  
        for (int i = 0; i < this.total; i++) {  
            this.visited[i] = false;                     // 初始化都未标记  
            this.dis[i] = this.matirx[s][i];     // 给源点的直接邻接点加上初始权值  
        }  
   
        this.visited[s] = true;  // 将源点s加入S集合  
        this.dis[s] = 0;   // 顶点到自身的距离为0,多此一举  
        int min = -1;        // 临时最短距离  
        int k = -1;          // 每次找到距离最短的点
  
//        this.printDis();  //每次都打印距离dis
  
        // 源点s到其它顶点(共total-1个)的最短距离
        for (int i = 1; i < this.total; i++) {  
            // 从当前最新的,源点到其它各顶点的距离信息数组dis[]中,找到一个没有标记过的,  
            // 并且距离(从源点到该某顶点)最短的顶点  
            min = MAX;  
            for (int j = 0; j < this.total; j++) {  
                if (this.visited[j]==false && this.dis[j] < min) {  
                    min = this.dis[j];  
                    k = j;  
                }  
            }  
   
            this.visited[k] = true;  // 找到的k加入S集合
  
           //距离校正  
            for (int j = 0; j < this.total; j++) {  
                if ((this.visited[j] == false) && (this.matirx[k][j] + this.dis[k]) < this.dis[j]) {  //最重要部分,j没访问过,且(k到j的距离)+(源点到k的距离) <(源点到j的距离)
                    this.dis[j] = this.matirx[k][j] + this.dis[k];  
                }  
            }    
            this.printDis();  //打印dis数组
        }  
    }  
  
    /** 
     * Dijkstra算法-(迪杰斯特拉)算法之优先队列实现 
     */  
    public void dijkstraPQ() {  
        // Item是PriorityQueue中元素,实现了Comparable接口,优先队列用此接口进行排序  
        class Item implements Comparable<Item> {  
            public int idx;            // 节点在数组的下标  
            public int weight;         // 到该节点的临时最小权值和  
  
            public Item(int idx, int weight) {  
                this.idx = idx;  
                this.weight = weight;  
            }   
            @Override  
            public int compareTo(Item item) {  
                if (this.weight == item.weight) {  
                    return 0;  
                } else if (this.weight < item.weight) {  
                    return -1;  
                } else {  
                    return 1;  
                }  
            }  
        }  
  
        // 值较小的元素总是在优先队列的头部,值较大的元素总是在优先队列的尾部  
        PriorityQueue<Item> pq = new PriorityQueue<Item>();      
        pq.offer(new Item(0, 0));  //源点(即起点)入队列  
  
        Item itm = null;  
        while (!pq.isEmpty()) {  
            itm = pq.poll();  //取出
           
            int idx = itm.idx;        // 节点下标               
            int weight = itm.weight;  // 到该节点的最小权值和 
  
            // 如果该元素还未标记,则更新dis数组
            if (this.visited[idx] == false) {  
                this.dis[idx] = weight;  
            }  
  
            // 找出该元素(假设A)的所有未标记的邻接点(假设B)  
            // 则,源点到B的距离可表示为:(源点到A的距离) + (A到B的距离)  
            // 将源点到B的距离加入到优先队列中  
            for (int i = 0; i < this.total; i++) {  
                if (this.visited[i] == false) {  
                    pq.offer(new Item(i, this.dis[idx] + this.matirx[idx][i]));  
                }  
            }  
        }  
    }  
    
    //打印个dis数组
    private void printDis() {  
        for (int t : this.dis) {  
            System.out.print(t + ","); 
        }  
       System.out.println();
    }  
    
    
//2.floyd最短路径,图中各个顶点间的最短路径
    /*
     * floyd最短路径。
     * 即,统计图中各个顶点间的最短路径。
     *
     * 参数说明:
     *     path -- 路径。path[i][j]=k表示,"顶点i"到"顶点j"的最短路径会经过顶点k。
     *     dist -- 长度数组。即,dist[i][j]=sum表示,"顶点i"到"顶点j"的最短路径的长度是sum。
     */
    public void floyd(int[][] path, int[][] dist) {

        // 初始化
        for (int i = 0; i < nodes.length; i++) {
            for (int j = 0; j < nodes.length; j++) {
                dist[i][j] = matirx[i][j];    // "顶点i"到"顶点j"的路径长度为"i到j的权值"。
                path[i][j] = j;                //*** "顶点i"到"顶点j"的最短路径是经过顶点j。
            }
        }

        // 计算最短路径
        for (int k = 0; k < nodes.length; k++) {
            for (int i = 0; i < nodes.length; i++) {
                for (int j = 0; j < nodes.length; j++) {

                    // 如果经过下标为k顶点路径比原两点间路径更短,则更新dist[i][j]和path[i][j]
                    int tmp = (dist[i][k]==MAX || dist[k][j]==MAX) ? MAX : (dist[i][k] + dist[k][j]);
                    if (tmp < dist[i][j]) {
                        // "i到j最短路径"对应的值设,为更小的一个(即经过k)
                        dist[i][j] = tmp;
                        // "i到j最短路径"对应的路径,经过k
                        path[i][j] = path[i][k];   //此时 path[i][k]即为k
                    }
                }
            }
        }
        
     // 打印floyd最短路径的结果
        System.out.printf("floyd dis: \n");
        for (int i = 0; i < nodes.length; i++) {
            for (int j = 0; j < nodes.length; j++)
                System.out.printf("%s  ", dist[i][j]==999?"m":dist[i][j]);
            System.out.println();
        }
        
        // 打印floyd路径结果
        System.out.printf("floyd path: \n");
        for (int i = 0; i < nodes.length; i++) {
            for (int j = 0; j < nodes.length; j++)
//                System.out.printf("%s  ", dist[i][j]==999?"m":dist[i][j]);
            	System.out.print(path[i][j]+" ");
            System.out.println();
        }
    }
  

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值