zoukankan      html  css  js  c++  java
  • 无向图

    无向图

    术语表

    定义:图是由一组顶点和一组能够将两个顶点相连的边组成的。
    特殊的图:

    • 自环:即一条连接一个顶点和其自身的边。
    • 连接同一对顶点的两条边称为平行边。

    数学家常常将含有平行边的图称为多重图,将没有平行边或自环的图称为简单图

    路径和环

    定义:在图中,路径是由边顺序连接的一系列顶点。简单路径是一条没有重复顶点的路径。环是一条至少含有一条边且起点和终点相同的路径。简单环是一条(除了起点和终点必须相同之外)不含有重复顶点和边的环。路径或者环的长度为其中所包含的边数。
    大多数情况下省略掉简单二字。

    连通图

    定义:如果从任意一个顶点都存在一条路径到达另一个任意顶点,我们称这幅图是连通图。一幅非连通的图由若干连通的部分组成,它们都是其极大连通子图。

    定义:树是一幅无环连通图。互不相连的树组成的集合称为森林。连通图的生成树是它的一幅子图,它含有图中的所有顶点且是一棵树。图的生成树森林是它的所有连通子图的生成树的集合。
    当且仅当一幅含有V个结点的图G满足下列5个条件之一时,它就是一棵树:

    • G有V-1条边且不含有环
    • G有V-1条边且是连通的
    • G是连通的,但删除任意一条边都会使它不再连通
    • G是无环图,但添加任意一条边都会产生一条环
    • G中的任意一对顶点之间仅存在一条简单路径

    无向图API

    public class Graph
    Graph(int V) 创建一个含有V个顶点但不含有边的图
    Graph(In in) 从标准输入流in读入一幅图
    int V() 顶点数
    int E() 边数
    void addEdge(int v,int w) 向图中添加一条边v-w
    Iterable adj(int v) 和v相邻的所有顶点
    String toString() 对象的字符串表示

    常用图处理代码

    无向图的表示

    一般来说有三种表示方法:

    • 邻接矩阵:我们可以使用一个V*V的布尔矩阵。定义v行w列的元素为true当且仅当顶点v和顶点w之间有相连的边。
    • 边的数组:使用Edge类,含有两个int变量表示两个顶点,但是实现adj()方法需要检查图中所有的边。
    • 邻接表数组:使用以顶点为索引的列表数组。其中每个元素都是和该顶点相邻的顶点列表。

    我们在选择的时候,实现图的API包含两个要求:

    1. 它必须为可能在应用中碰到的各种类型的图预留出足够的空间。
    2. Graph的实例方法的实现一定要快。

    显然,邻接表数组满足以上两个条件。

    邻接表的数据结构

    无向图的实现

    1
    2
    3
    4
    5
    6
    < 大专栏  无向图span class="line">7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class Graph{
    private final int V; //顶点数目
    private int E; //边的数目
    private Bag<Integer>[] adj; //邻接表
    public Graph(int V){
    this.V=V;
    this.E=0;
    adj=(Bag<Integer>[]) new Bag[V]; //创建邻接表
    for(int v=0;v<V;v++){ //将所有链表初始化为空
    adj[v]=new Bag<Integer>();
    }
    }
    public Graph(In in){
    this(in.readInt()); //读取V并将图初始化
    int E=in.readInt(); //读取E
    for(int i=0;i<E;i++){
    // 添加一条边
    int v=in.readInt(); //读取一个顶点
    int w=in.readInt(); //读取另一个顶点
    addEdge(v,w); //添加一条连接它们的值
    }
    }
    public int V(){return V;}
    public int E(){return E;}
    public void addEdge(int v,int w){
    adj[v].add(w); //将w添加到v的链表中
    adj[w].add(v); //将v添加到w的链表中
    E++;
    }
    public Iterable<Integer> adj(int v){
    return adj[v];
    }
    }

    性能分析

    数据结构 所需空间 添加一条边v-w 检查w和v是否相邻 遍历v的所有相邻顶点
    边的列表 E 1 E E
    邻接矩阵 V^2 1 1 V
    邻接表 E+V 1 degree(v) degree(v)
    邻接集 E+V logV logV logV+degree(v)
  • 相关阅读:
    Why does the memory usage increase when I redeploy a web application?
    lsof
    Advising controllers with the @ControllerAdvice annotation
    springMVC(一): 整体请求过程概述
    正则表达式30分钟入门教程
    Python基本语法_强制数据类型转换
    Python 正则表达式入门(初级篇)
    python实现简单爬虫功能
    在python3.3后urllib2已经不能再用,只能用urllib.request来代替
    JSON
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12284429.html
Copyright © 2011-2022 走看看