数据结构 - 图(Graph)- 目录


图(Graph)

在这里插入图片描述

  • 图由顶点(vertex)和边(edge)组成,通常表示为G = (V, E)
  1. G标识一个图,V是顶点集,E是边集
  2. 顶点集V有穷且非空
  3. 任意两个顶点之间都可以用边来表示它们之间的关系,边集E可以是为空的
    在这里插入图片描述

图的应用举例

  • 图结构的应用极其广泛
  1. 社交网络
  2. 地图
  3. 游戏开发

  4. 在这里插入图片描述

有向图(Directed Graph)

  • 有向图的边是有明确方向的
    在这里插入图片描述
  • 有向无环图(Directed Acyclic Graph,简称DAG)
  • 如果一个有向图,从任意顶点出发无法经过若干条边回到该顶点,那么它就是一个有向无环图
    在这里插入图片描述

出度、入度

出度、入度适用于有向图

  • 出度(Out-degree)
  1. 一个顶点的出度为x,是指有x条边以该顶点为起点
  2. 顶点11的出度是3
  • 入度(In-degree)
  1. 一个顶点的入度为x,是指有x条边以该顶点为终点
  2. 顶点11的入度是2
    在这里插入图片描述

无向图(Undirected Graph)

  • 无向图的边是无方向的
    在这里插入图片描述
  • 效果类似于下面的有向图
    在这里插入图片描述

混合图(Mixed Graph)

  • 混合图的边可能是无向的,也可能是有向的
    在这里插入图片描述

简单图、多重图

  • 平行边
  1. 无向图中,关联一对顶点的无向边如果多于1条,则称这些边为平行边
  2. 在有向图中,关联一对顶点的有向边如果多于1条,并且它们的方向相同,则称这些边为平行边
  • 多重图(Multi Graph)
    有平行边或者有自环的图
  • 简单图(Simple Graph)
    既没有平行边也没有自环的图
  • 博客中讨论的基本都是简单图
    在这里插入图片描述

无向完全图( Undirected Complete Graph)

  • 无向完全图的任意两个顶点之间都存在边
  • n个顶点的无向完全图有n (n - 1) / 2条边
  • (n - 1) + (n - 2) + (n - 3) + … + 3 + 2 + 1
    在这里插入图片描述

有向完全图( Directed Complete Graph)

  • 有向完全图的任意两个顶点之间都存在方向相反的两条边
  • n个顶点的有向完全图有n(n-1)条边
    在这里插入图片描述
  • 稠密图(Dense Graph):边数接近于或等于完全图
  • 疏密秃(Sparse Graph):边数远远少于完全图

有权图( Weighted Graph)

  • 有权图的边可以拥有权值(Weight)
    在这里插入图片描述

连通图( Connected Graph)

  • 如果顶点x和y之间存在可相互抵达的路径(直接或者间接的路径),则称x和y是连通的
  • 如果无向图G中任意2个顶点都是连通的,则称G为连通图
    在这里插入图片描述

连通分量( Connected Component)

  • 如果顶点x和y之间存在可相互抵达的路径(直接或者间接的路径),则称x和y是连通的
  • 连通图只有一个连通分量,即其自身;非连通的无向图有多个连通分量
  • 下面的无向图有3个连通分量
    在这里插入图片描述

强连通图( Strongly Connected Graph)

  • 如果有向图G中任意2个顶点都是连通的,则称G为强连通图
    在这里插入图片描述

强连通分量( Strongly Connected Component)

  • 强连通分量:有向图的极大强连通子图
  • 强连通图只有一个强连通分量,即其自身;非强连通的有向图有多个强连通分量
    在这里插入图片描述

图的实现方案

  • 图由2种常见的实现方案
  1. 邻接矩阵(Adjacency Matrix)
  2. 邻接表(Adjacency List)

邻接矩阵(Adjacency Matrix)

  • 邻接矩阵的存储方式
  1. 一位数组存放顶点信息
  2. 二位数组存放边信息
  • 邻接矩阵比较适合稠密图
  • 不然会比较浪费内存
    在这里插入图片描述

邻接矩阵 - 有权图

在这里插入图片描述

邻接表(Adjacency List)

在这里插入图片描述

邻接表- 有权图

在这里插入图片描述


图的基础接口

int verticesSize();
int edgesSize();

void addVertex(V v);
void removeVertex(V v);

void addEdge(V fromV, V toV);
void addEdge(V fromV, V toV, E weight);
void removeEdge(V fromV, V toV);

顶点的定义

private static class Vertex<V, E> {
    V value;
    Set<Edge<V, E>> inEdges = new HashSet<>();
    Set<Edge<V, E>> outEdges = new HashSet<>();
    Vertex(V value) {
        this.value = value;
    }
    @override
    public boolean equals(Object obj) {
        return Objects.eqauls(value, ((Vertex<V, E> obj).value));
   }
   @override
   public int hashCode() {
       return value == null ? 0 : value.hashCode();
   }
}

边的定义

private static class Edge<V, E> {
    Vertex<V, E> from;
    Vertex<V, E> to;
    E weight;
    public boolean equals(Object obj) {
        Edge<V, E> edge = (Edge<V, E>) obj;
        return from.equals(edge.from) && to.equal(edge.to);
    }
    public int hashCode() {
        return form.hashCode() * 31 + to.hashCode();
   }
}
发布了163 篇原创文章 · 获赞 18 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/songzhuo1991/article/details/103069784