带权图,每条边相应都有一组值:

不同的权图可以有不同类型的值。

邻接矩阵:

0          0             1            2            3

0          0            0.12        0            0

1          0.12        0            0.34       0.52

2          0            0.34        0            0.22

3          0            0.52         0.28       0

邻接表:

0     {to:1,w:0.12}

1     {to:0,w:0.12}、 {to:2,w:0.34}、 {to:3,w:0.52}

2      {to:1,w:0.34}、 {to:3,w:0.28}

3      {to:1,w:0.52}、 {to:2,w:0.28}

对权图边与值封装成一个类:

// 边
public class Edge<Weight extends Number & Comparable> implements Comparable<Edge>{//有向边,从a指向bprivate 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;}}
}

稠密图:邻接矩阵。

import java.util.Vector;// 稠密图 - 邻接矩阵
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].wt()+"\t");}else{System.out.print("NULL\t");}}System.out.println();}}// 返回图中一个顶点的所有邻边// 由于java使用引用机制,返回一个Vector不会带来额外开销,public Iterable<Edge<Weight>> adj(int v) {assert v >= 0 && v < n;Vector<Edge<Weight>> adjV = new Vector<Edge<Weight>>();for(int i = 0 ; i < n ; i ++ ){if( g[v][i] != null ){adjV.add( g[v][i] );}}return adjV;}
}

稀疏图:邻接表。

import java.util.Vector;// 稀疏图 - 邻接表
public class SparseWeightedGraph<Weight extends Number & Comparable>implements WeightedGraph {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;} // 返回边的个数// 向图中添加一个边, 权值为weightpublic 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];}
}

利用稠密图和稀疏图对文件图进行读取:

interface WeightedGraph<Weight extends Number & Comparable> {public int V();public int E();public void addEdge(Edge<Weight> e);boolean hasEdge( int v , int w );void show();public Iterable<Edge<Weight>> adj(int v);
}
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<Double> 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 {File file = new File(filename);if (file.exists()) {FileInputStream fis = new FileInputStream(file);scanner = new Scanner(new BufferedInputStream(fis), "UTF-8");scanner.useLocale(Locale.ENGLISH);}elsethrow new IllegalArgumentException(filename + " doesn't exist.");}catch (IOException ioe) {throw new IllegalArgumentException("Could not open " + filename, ioe);}}}
public class Main {// 测试通过文件读取图的信息public static void main(String[] args) {// 使用两种图的存储方式读取testG1.txt文件String filename = "testG1.txt";SparseWeightedGraph<Double> g1 = new SparseWeightedGraph<Double>(8, false);ReadWeightedGraph readGraph1 = new ReadWeightedGraph(g1, filename);System.out.println("test G1 in Sparse Weighted Graph:");g1.show();System.out.println();DenseWeightedGraph<Double> g2 = new DenseWeightedGraph<Double>(8, false);ReadWeightedGraph readGraph2 = new ReadWeightedGraph(g2 , filename );System.out.println("test G1 in Dense Graph:");g2.show();System.out.println();}
}

图:

8 16
4 5 .35
4 7 .37
5 7 .28
0 7 .16
1 5 .32
0 4 .38
2 3 .17
1 7 .19
0 2 .26
1 2 .36
1 3 .29
2 7 .34
6 2 .40
3 6 .52
6 0 .58
6 4 .93

Java 算法:带权图Weighted Graph相关推荐

  1. Java数据结构与算法:无向图,有向图,带权图,图的遍历,最小生成树

    文章目录 无向图 有向图 带权图 图的遍历 广度优先遍历 深度优先遍历 最小生成树 无向图 前面了解到树是有单一根结点的非线性结构,图(graph)也是一种非线性结构,其中的结点可以与许多其他的结点相 ...

  2. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  3. 求的带权图最小生成树的Prim算法和Kruskal算法

    求的带权图最小生成树的Prim算法和Kruskal算法 最小生成树的概念 最小生成树其实是最小权重生成树的简称. 一个连通图可能有多个生成树.当图中的边具有权值时,总会有一个生成树的边的权值之和小于或 ...

  4. 邻接表实现的有向带权图 及 图算法(C++)

    邻接表实现的有向带权图 相关概念 声明和定义 实现 1. 构造函数 2. 析构函数 3. 深度优先遍历 4. 广度优先遍历 5. 获取顶点在邻接表中对应的下标 6. 添加顶点 7. 移除顶点 8. 添 ...

  5. python无向带权图

    无向无权图见另一篇文章<python无向无权图结构>,这篇讲无向带权图,并且给出一个地铁线路例子. # -*- coding: UTF-8 -*- #!/usr/bin/python#-- ...

  6. c语言图的无向网存储,C语言——无向带权图邻接矩阵的建立

    #include #include "Graph.h" #define MAX_INT 32767 /* #define vnum 20 #define MAX_INT = 327 ...

  7. 数据结构——图-有向带权图的邻接表

    #include <stdio.h> #include <stdlib.h> #define VertexType char //顶点的数据类型(char) #define V ...

  8. 数据结构——图-有向带权图的邻接表基础

    #include <stdio.h> #include <stdlib.h> #define VertexType char //顶点的数据类型(char) #define V ...

  9. 实现有向带权图抽象数据类型

    题目 图是一种使用广泛的数据结构.本次实验要求设计有向带权图的抽象数据类型,实现图的构造.顶点的增删查,边的增删改.深度优先遍历与广度优先遍历.单源最短路径.多源最短路径.判断图中是否存在负环. 效果 ...

  10. 6.1图的定义、无向图、有向图、连通图、强连通图、带权图

    1. 知识总览 2. 图的定义 3. 图逻辑结构的应用 4. 无向图.有向图 5. 简单图.多重图 6. 顶点的度.入度.出度 7. 连通图.强连通图 8. 研究图的局部–子图 9. 连通分量 10. ...

最新文章

  1. Python访问MySQL数据库
  2. 分布式存储的三个基本问题
  3. 网络安全netstat监听网络状态。
  4. 不一样的STAR法则
  5. 如何挽回一个快要“变心”的买家?
  6. 基于float的几种布局
  7. Linux下文件的多进程拷贝
  8. SQL 语句还原SQL Server数据库
  9. Java笔记-JPA保存数据时指定列不插入提交(CURRENT_TIMESTAMP)
  10. 从0到1构建支撑企业自动化运维体系
  11. Linux PPP实现源码分析-2
  12. 年度加密漏洞提前锁定:Java JDK 加密实现漏洞可用于伪造凭据
  13. 特斯拉电池检测_特斯拉风格的割草机,也是采用电池供电
  14. 前端面试常问的问题(必须掌握)
  15. Learn Git Branching 答案汇总
  16. op 消除 消除自激振荡
  17. Can't connect to MySQL server on 'localhost'(10038)的解决方案
  18. MySQL中Lob与JPA映射
  19. JAVA与PHP之间进行aes加密解密
  20. TMF和Frameworx

热门文章

  1. CUDA优化LBP(loopy belief propegation)
  2. Aladdin推出软件智能卡和一次性密码认证解决方案
  3. pca降维算法java_PCA降维算法
  4. 关于网络连接里无虚拟网络适配器的解决办法
  5. LZJ的python学习第一天
  6. html5简单的数字加法效果
  7. 算法入门之lowB三人组---冒泡排序、选择排序、插入排序 【python版-详解】
  8. js更换自定义鼠标指针图片
  9. js判断设备是ios还是安卓,以及微信端
  10. 阿里P9:聊聊大厂晋升的“潜规则”