数据结构与算法分析(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
- 数据结构与算法分析(Java语言描述)(30)—— 有权图的实现
- 数据结构与算法分析(Java语言描述)(31)—— 使用 Prim 算法求有权图的最小生成树(MST)
- 数据结构与算法分析(Java语言描述)(32)—— 使用 Kruskal 算法求有权图的最小生成树
- 《数据结构与算法分析——java语言描述(第二版)》中树实现的一点思考
- (数据结构与算法分析 四)------数组循环队列的实现( Java语言描述)
- (数据结构与算法分析 五)------二叉查找树的实现( Java语言描述)
- (数据结构与算法分析 六)------散列表的实现( Java语言描述)
- 数据结构与算法分析(Java语言描述)(26)—— 邻接矩阵表示稠密图
- 读书笔记:数据结构与算法分析(Java语言描述)——数据结构概论
- 数据结构与算法分析(Java 语言描述)(35)—— 使用两个栈实现一个队列
- 数据结构与算法分析(Java 语言描述)(36)—— 使用两个队列实现一个栈
- 数据结构与算法分析——Java语言描述
- 《数据结构与算法分析—Java语言描述》pdf
- 数据结构与算法分析(Java语言描述)(8)—— (随机)快速排序
- 数据结构与算法分析(Java语言描述)(9)—— (双轴)快速排序
- 数据结构与算法分析(Java语言描述)(1)—— 选择排序
- 数据结构与算法分析(Java语言描述)(2)—— 插入排序
- 数据结构与算法分析(Java语言描述)(3)—— 冒泡排序
- jsp 网站 mysql 数据库连接 tomcat 服务器配置server
- Docker-ce+Ubuntu 16.04环境配置
- 简单写个好理解的Builder设计模式
- sql时间参数输出
- Pie
- 数据结构与算法分析(Java语言描述)(30)—— 有权图的实现
- HDFS实现其高可靠性的策略及机制
- freemarker 模版静态化
- “敲代码”学编程的正确方式
- 《HTTP权威指南》学习笔记(1)第1章HTTP概述(关键词:计算机网络/HTTP)
- 【Tensorflow slim】 slim.arg_scope的用法
- Android L版本上codegen.dws文件的路径.docx
- 木乃伊迷宫
- C语言编程之函数调用规则