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)
  • 相关阅读:
    1.4.2.3. SETUP(Core Data 应用程序实践指南)
    1.4.2.2. PATHS(Core Data 应用程序实践指南)
    1.4.2.1. FILES(Core Data 应用程序实践指南)
    1.4.2. 实现 Core Data Helper 类(Core Data 应用程序实践指南)
    1.4.1. Core Data Helper 简介(Core Data 应用程序实践指南)
    1.4. 为现有的应用程序添加 Core Data 支持(Core Data 应用程序实践指南)
    1.3.2. App Icon 和 Launch Image(Core Data 应用程序实践指南)
    1.3.1. 新建Xcode项目并设置故事板(Core Data 应用程序实践指南)
    php验证邮箱是否合法
    如何使js函数异步执行
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12284429.html
Copyright © 2011-2022 走看看