图论基础和表示

一、概念及其介绍

图论(Graph Theory)是离散数学的一个分支,是一门研究图(Graph)的学问。

图是用来对对象之间的成对关系建模的数学结构,由"节点"或"顶点"(Vertex)以及连接这些顶点的"边"(Edge)组成。

值得注意的是,图的顶点集合不能为空,但边的集合可以为空。图可能是无向的,这意味着图中的边在连接顶点时无需区分方向。否则,称图是有向的。下面左图是一个典型的无向图结构,右图则属于有向图。本章节介绍的图都是无向图。

图的分类:无权图和有权图,连接节点与节点的边是否有数值与之对应,有的话就是有权图,否则就是无权图。

**图的连通性:**在图论中,连通图基于连通的概念。在一个无向图 G 中,若从顶点 i 到顶点 j 有路径相连(当然从j到i也一定有路径),则称 i 和 j 是连通的。如果 G 是有向图,那么连接i和j的路径中所有的边都必须同向。如果图中任意两点都是连通的,那么图被称作连通图。如果此图是有向图,则称为强连通图(注意:需要双向都有路径)。图的连通性是图的基本性质。

**完全图:**完全是一个简单的无向图,其中每对不同的顶点之间都恰连有一条边相连。

**自环边:**一条边的起点终点是一个点。

**平行边:**两个顶点之间存在多条边相连接。

二、适用说明

图可用于在物理、生物、社会和信息系统中建模许多类型的关系和过程,许多实际问题可以用图来表示。因此,图论成为运筹学、控制论、信息论、网络理论、博弈论、物理学、化学、生物学、社会科学、语言学、计算机科学等众多学科强有力的数学工具。在强调其应用于现实世界的系统时,网络有时被定义为一个图,其中属性(例如名称)之间的关系以节点和或边的形式关联起来。

三、图的表达形式

**邻接矩阵:**1 表示相连接,0 表示不相连。

**邻接表:**只表达和顶点相连接的顶点信息

邻接表适合表示稀疏图 (Sparse Graph)

邻接矩阵适合表示稠密图 (Dense Graph)

Java 实例代码

(1) 邻接矩阵

src/runoob/graph/DenseGraph.java 文件代码:

复制代码
package runoob.graph;

/**
 * 邻接矩阵
 */
public class DenseGraph {
    // 节点数
    private int n;
    // 边数
    private int m;
    // 是否为有向图
    private boolean directed;
    // 图的具体数据
    private boolean[][] g;

    // 构造函数
    public DenseGraph( int n , boolean directed ){
        assert n >= 0;
        this.n = n;
        this.m = 0;
        this.directed = directed;
        // g初始化为n*n的布尔矩阵, 每一个g[i][j]均为false, 表示没有任和边
        // false为boolean型变量的默认值
        g = new boolean[n][n];
    }
    // 返回节点个数
    public int V(){ return n;}
    // 返回边的个数
    public int E(){ return m;}

    // 向图中添加一个边
    public void addEdge( int v , int w ){
        assert v >= 0 && v < n ;
        assert w >= 0 && w < n ;
        if( hasEdge( v , w ) )
            return;
        g[v][w] = true;
        if( !directed )
            g[w][v] = true;
        m ++;
    }

    // 验证图中是否有从v到w的边
    boolean hasEdge( int v , int w ){
        assert v >= 0 && v < n ;
        assert w >= 0 && w < n ;
        return g[v][w];
    }
}

(2)邻接表

src/runoob/graph/SparseGraph.java 文件代码:

复制代码
package runoob.graph;

import java.util.Vector;

/**
 * 邻接表
 */
public class SparseGraph {
    // 节点数
    private int n;
    // 边数
    private int m;
    // 是否为有向图
    private boolean directed;
    // 图的具体数据
    private Vector<Integer>[] g;

    // 构造函数
    public SparseGraph( int n , boolean directed ){
        assert n >= 0;
        this.n = n;
        this.m = 0;  
        this.directed = directed;
        // g初始化为n个空的vector, 表示每一个g[i]都为空, 即没有任和边
        g = (Vector<Integer>[])new Vector[n];
        for(int i = 0 ; i < n ; i ++)
            g[i] = new Vector<Integer>();
    }
    // 返回节点个数
    public int V(){ return n;}
    // 返回边的个数
    public int E(){ return m;}
    // 向图中添加一个边
    public void addEdge( int v, int w ){
        assert v >= 0 && v < n ;
        assert w >= 0 && w < n ;
        g[v].add(w);
        if( v != w && !directed )
            g[w].add(v);
        m ++;
    }

    // 验证图中是否有从v到w的边
    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) == w )
                return true;
        return false;
    }
}
相关推荐
天选之女wow13 小时前
【代码随想录算法训练营——Day60】图论——94.城市间货物运输I、95.城市间货物运输II、96.城市间货物运输III
android·算法·图论
foundbug99921 小时前
基于超像素和基于图论的图像分割方法
图论
CodeWizard~2 天前
AtCoder Beginner Contest 430赛后补题
c++·算法·图论
天选之女wow3 天前
【代码随想录算法训练营——Day58】图论——117.软件构建、47. 参加科学大会
算法·图论
earthzhang20214 天前
【2051】【例3.1】偶数
开发语言·数据结构·算法·青少年编程·图论
apcipot_rain4 天前
CSP集训错题集 第八周 主题:基础图论
算法·图论
天选之女wow4 天前
【代码随想录算法训练营——Day57(Day56周日休息)】图论——53.寻宝
算法·图论
极客数模4 天前
2025年(第六届)“大湾区杯”粤港澳金融数学建模竞赛准备!严格遵循要求,拿下大奖!
大数据·python·数学建模·金融·分类·图论·boosting
岑梓铭5 天前
《考研408数据结构》第七章(6.1~6.3图的概念、存储方式、深/广度遍历)复习笔记
数据结构·笔记·考研·算法·图论·408·ds
天选之女wow5 天前
【代码随想录算法训练营——Day53】图论——110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长
算法·深度优先·图论