数据结构与算法分析(Java语言描述)(30)—— 有权图的实现

来源:互联网 发布:校园网络安全教育讲座 编辑:程序博客网 时间:2024/05/16 17:30

使用 Edge.java 存放两节点之间的边

Edge.java

package com.dataStructure.weight_graph;// 有权图的边public class Edge<Weight extends Number & Comparable> implements Comparable<Edge> {    private int v;  // 边的一个端点 v    private int w;  // 边的另一个端点 w    private Weight weight;  // 边的权重    // 构造函数    public Edge(int v, int w, Weight weight) {        this.v = v;        this.w = w;        this.weight = weight;    }    // 构造函数    public Edge(Edge<Weight> edge) {        this.v = edge.v;        this.w = edge.w;        this.weight = edge.weight;    }    public String toString() {  // 输出边的信息        return "" + this.v + "-" + this.w + ":" + this.weight;    }    public int getV() { // 返回节点 v        return v;    }    public int getW() { // 返回节点 w        return w;    }    public Weight getWeight() { // 返回边的权重        return weight;    }    public int getAnotherNode(int x) {  // 输入边的一个端点,输出边的另一个端点        return x == v ? v : w;    }    public int compareTo(Edge anotherEdge){ // 比较两个边的权重大小        if (this.weight.compareTo(anotherEdge.weight) > 0)            return 1;        else if (this.weight.compareTo(anotherEdge.weight) < 0)            return -1;        else            return 0;    }}//public class Edge<Weight extends Number & Comparable> implements Comparable<Edge> {////    private int a, b;    // 边的两个端点//    private Weight weight;  // 边的权值////    public Edge(int a, int b, Weight weight)//    {//        this.a = a;//        this.b = b;//        this.weight = weight;//    }////    public Edge(Edge<Weight> e)//    {//        this.a = e.a;//        this.b = e.b;//        this.weight = e.weight;//    }////    public int v(){ return a;} // 返回第一个顶点//    public int w(){ return b;} // 返回第二个顶点////    public Weight wt(){ return weight;}    // 返回权值////    // 给定一个顶点, 返回另一个顶点//    public int other(int x){//        assert x == a || x == b;//        return x == a ? b : a;//    }////    // 输出边的信息//    public String toString(){//        return "" + a + "-" + b + ": " + weight;//    }////    // 边之间的比较//    public int compareTo(Edge that)//    {//        if( weight.compareTo(that.wt()) < 0 )//            return -1;//        else if ( weight.compareTo(that.wt()) > 0 )//            return +1;//        else//            return  0;//    }////}

WeightedGraph.java

package com.dataStructure.weight_graph;public interface WeightedGraph {    public int V();    public int E();    public void addEdge(Edge e);    boolean hasEdge(int v, int w);    void show();    public Iterable<Edge> adjacentNode(int v);}

DenseGraph.java

package com.dataStructure.weight_graph;import java.util.ArrayList;import java.util.List;// 稠密图 - 邻接矩阵public class DenseGraph implements WeightedGraph {    private int vertexCount;    // 节点数量    private int edgeCount;  // 边数    private Edge[][] adjacencyMatrix;   // 存放 Edge 的邻接矩阵    private boolean directed;   // 是否为有向图    // 构造函数,初始化私有字段    public DenseGraph(int vertexCount, boolean directed) {        this.vertexCount = vertexCount;        this.edgeCount = 0;        this.directed = directed;        adjacencyMatrix = new Edge[vertexCount][vertexCount];        for (int i = 0; i < vertexCount; i++)            for (int j = 0; j < vertexCount; j++)                adjacencyMatrix[i][j] = null;   // 邻接矩阵初始为空    }    public int V() {    // 返回节点数量        return vertexCount;    }    public int E() {    // 返回边数        return edgeCount;    }    public void addEdge(Edge e) {   // 添加一条边        if (hasEdge(e.getV(), e.getW()))            return;        adjacencyMatrix[e.getV()][e.getW()] = new Edge(e);        if( e.getV() != e.getW() && !directed )            adjacencyMatrix[e.getW()][e.getV()] = new Edge(e.getW(), e.getV(), e.getWeight());        edgeCount++;    }    public boolean hasEdge(int v, int w) {  // 判断两节点之间是否有边        return adjacencyMatrix[v][w] != null;    }    public void show() {    // 打印邻接矩阵        for( int i = 0 ; i < vertexCount ; i ++ ){            for( int j = 0 ; j < vertexCount ; j ++ )                if( adjacencyMatrix[i][j] != null )                    System.out.print(adjacencyMatrix[i][j].getWeight()+"\t");                else                    System.out.print("NULL\t");            System.out.println();        }    }    public Iterable<Edge> adjacentNode(int v) { // 获取邻接节点        List<Edge> list = new ArrayList<>();        for (int i = 0;i<adjacencyMatrix[v].length;i++){            if (adjacencyMatrix[v][i] != null)                list.add(adjacencyMatrix[v][i]);        }        return list;    }}//public class DenseWeightedGraph<Weight extends Number & Comparable>//        implements WeightedGraph{////    private int n;  // 节点数//    private int m;  // 边数//    private boolean directed;   // 是否为有向图//    private Edge<Weight>[][] g;         // 图的具体数据////    // 构造函数//    public DenseWeightedGraph( int n , boolean directed ){//        assert n >= 0;//        this.n = n;//        this.m = 0;    // 初始化没有任何边//        this.directed = directed;//        // g初始化为n*n的布尔矩阵, 每一个g[i][j]均为null, 表示没有任和边//        // false为boolean型变量的默认值//        g = new Edge[n][n];//        for(int i = 0 ; i < n ; i ++)//            for(int j = 0 ; j < n ; j ++)//                g[i][j] = null;//    }////    public int V(){ return n;} // 返回节点个数//    public int E(){ return m;} // 返回边的个数////    // 向图中添加一个边//    public void addEdge(Edge e){//////        assert e.v() >= 0 && e.v() < n ;////        assert e.w() >= 0 && e.w() < n ;//////        if( hasEdge( e.v() , e.w() ) )////            return;////////        g[e.v()][e.w()] = new Edge(e);////        if( e.v() != e.w() && !directed )////            g[e.w()][e.v()] = new Edge(e.w(), e.v(), e.wt());//////        m ++;//    }////    // 验证图中是否有从v到w的边//    public boolean hasEdge( int v , int w ){//        assert v >= 0 && v < n ;//        assert w >= 0 && w < n ;//        return g[v][w] != null;//    }////    // 显示图的信息//    public void show(){////        for( int i = 0 ; i < n ; i ++ ){//            for( int j = 0 ; j < n ; j ++ )//                if( g[i][j] != null )//                    System.out.print(g[i][j].getWeight()+"\t");//                else//                    System.out.print("NULL\t");//            System.out.println();//        }//    }////    // 返回图中一个顶点的所有邻边//    // 由于java使用引用机制,返回一个Vector不会带来额外开销,//    public Iterable<Edge<Weight>> adjacentNode(int v) {//        assert v >= 0 && v < n;//        List<Edge<Weight>> adjV = new ArrayList<>();//        for(int i = 0 ; i < n ; i ++ )//            if( g[v][i] != null )//                adjV.add( g[v][i] );//        return adjV;//    }//}

SparseGraph.java

package com.dataStructure.weight_graph;import java.util.ArrayList;import java.util.List;public class SparseGraph implements WeightedGraph {    private int vertexCount;    private int edgeCount;    private boolean directed;    private List<Edge>[] adjacencyTable;    public SparseGraph(int vertexCount, boolean directed) {        this.vertexCount = vertexCount;        this.edgeCount = 0;        this.directed = directed;        adjacencyTable = (ArrayList<Edge>[]) new ArrayList[vertexCount];        for (int i = 0; i < adjacencyTable.length; i++)                adjacencyTable[i] = new ArrayList<>();    }    public int V() {        return vertexCount;    }    public int E() {        return edgeCount;    }    public void addEdge(Edge e) {   // 添加一条边        if (hasEdge(e.getV(), e.getW()))            return;        adjacencyTable[e.getV()].add(new Edge(e));        if (e.getV() != e.getW() && !directed)            adjacencyTable[e.getW()].add(new Edge(e.getW(), e.getV(), e.getWeight()));        edgeCount++;    }    public boolean hasEdge(int v, int w) {  // 判断节点 v 和 w 之间是否有边        for (Edge edge:adjacencyTable[v])            if (edge.getAnotherNode(v) == w)                return true;        return false;    }    public void show() {    // 打印邻接表        for( int i = 0 ; i < vertexCount ; i ++ ){            System.out.print("vertex " + i + ":\t");            for( int j = 0 ; j < adjacencyTable[i].size() ; j ++ ){                Edge e = adjacencyTable[i].get(j);                System.out.print( "( to:" + e.getAnotherNode(i) + ",wt:" + e.getWeight() + ")\t");            }            System.out.println();        }    }    public Iterable<Edge> adjacentNode(int v) { // 返回邻接节点        return adjacencyTable[v];    }//    private int n;  // 节点数//    private int m;  // 边数//    private boolean directed;   // 是否为有向图//    private Vector<Edge<Weight>>[] g;   // 图的具体数据////    // 构造函数//    public SparseWeightedGraph( int n , boolean directed ){//        assert n >= 0;//        this.n = n;//        this.m = 0;    // 初始化没有任何边//        this.directed = directed;//        // g初始化为n个空的vector, 表示每一个g[i]都为空, 即没有任和边//        g = (Vector<Edge<Weight>>[])new Vector[n];//        for(int i = 0 ; i < n ; i ++)//            g[i] = new Vector<Edge<Weight>>();//    }////    public int V(){ return n;} // 返回节点个数//    public int E(){ return m;} // 返回边的个数////    // 向图中添加一个边, 权值为weight//    public void addEdge(Edge e){////        assert e.v() >= 0 && e.v() < n ;//        assert e.w() >= 0 && e.w() < n ;////        // 注意, 由于在邻接表的情况, 查找是否有重边需要遍历整个链表//        // 我们的程序允许重边的出现////        g[e.v()].add(new Edge(e));//        if( e.v() != e.w() && !directed )//            g[e.w()].add(new Edge(e.w(), e.v(), e.wt()));////        m ++;//    }////    // 验证图中是否有从v到w的边//    public boolean hasEdge( int v , int w ){////        assert v >= 0 && v < n ;//        assert w >= 0 && w < n ;////        for( int i = 0 ; i < g[v].size() ; i ++ )//            if( g[v].elementAt(i).other(v) == w )//                return true;//        return false;//    }////    // 显示图的信息//    public void show(){////        for( int i = 0 ; i < n ; i ++ ){//            System.out.print("vertex " + i + ":\t");//            for( int j = 0 ; j < g[i].size() ; j ++ ){//                Edge e = g[i].elementAt(j);//                System.out.print( "( to:" + e.other(i) + ",wt:" + e.wt() + ")\t");//            }//            System.out.println();//        }//    }////    // 返回图中一个顶点的所有邻边//    // 由于java使用引用机制,返回一个Vector不会带来额外开销,//    public Iterable<Edge<Weight>> adj(int v) {//        assert v >= 0 && v < n;//        return g[v];//    }}

ReadWeightedGraph.java

package com.dataStructure.weight_graph;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.util.Scanner;import java.util.Locale;import java.util.InputMismatchException;import java.util.NoSuchElementException;// 通过文件读取有全图的信息public class ReadWeightedGraph{    private Scanner scanner;    // 由于文件格式的限制,我们的文件读取类只能读取权值为Double类型的图    public ReadWeightedGraph(WeightedGraph graph, String filename){        readFile(filename);        try {            int V = scanner.nextInt();            if (V < 0)                throw new IllegalArgumentException("number of vertices in a Graph must be nonnegative");            assert V == graph.V();            int E = scanner.nextInt();            if (E < 0)                throw new IllegalArgumentException("number of edges in a Graph must be nonnegative");            for (int i = 0; i < E; i++) {                int v = scanner.nextInt();                int w = scanner.nextInt();                Double weight = scanner.nextDouble();                assert v >= 0 && v < V;                assert w >= 0 && w < V;                graph.addEdge(new Edge<Double>(v, w, weight));            }        }        catch (InputMismatchException e) {            String token = scanner.next();            throw new InputMismatchException("attempts to read an 'int' value from input stream, but the next token is \"" + token + "\"");        }        catch (NoSuchElementException e) {            throw new NoSuchElementException("attemps to read an 'int' value from input stream, but there are no more tokens available");        }    }    private void readFile(String filename){        assert filename != null;        try {            String basePath = (new File(this.getClass().getResource("").getPath())).toString();            File file = new File(basePath + filename);            if (file.exists()) {                FileInputStream fis = new FileInputStream(file);                scanner = new Scanner(new BufferedInputStream(fis), "UTF-8");                scanner.useLocale(Locale.ENGLISH);            }            else                throw new IllegalArgumentException(filename + " doesn't exist.");        }        catch (IOException ioe) {            throw new IllegalArgumentException("Could not open " + filename, ioe);        }    }}

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

阅读全文
0 0
原创粉丝点击