图论的简单知识结构

时间:2022-12-18 11:20:30

本文出自:Svitter的Blog 以及 Github

图论Graph

8/8/2014 9:23:16 AM

图的基本概念

图的定义 Defination

  • 图是由顶点集合(Vertex)及顶点间的关系集合(边Edge)组成的一种数据结构: > Graph=( V, E )
  • 顶点Vertex

    V = {x | x ∈ 某个数据对象}

  • 边的集合Edge

    E = {(x, y) | x,y ∈ V }

    E = {(x, y) | x, y ∈ V && path(x,y)

  • Path(x, y)表示从x到y的一条单向通路——说明什么?<!--(有方向)-->

  • 由此我们可以得出

有向图 && 无向图 ||( Directed graph && Oriented graph)

  • 在有向图中,顶点对是有序的。

  • 在无向图中,顶点对( x, y )是无序的。

完全图 Complete graph

  • 有n个顶点的无向图有n(n-1)/2条边,则此图为无向完全图(为什么?)<!--除了他本身,可以到达具有任何一个顶点的边 -->
  • 有n个顶点的有向图有n(n-1)条边,则此图为有向完全图 (这又是为什么?)

图论的简单知识结构


邻接顶点 (Adjacency Vertex)

  • 如果(u, v) 是 E(G) 中的一条边,则称 u 与 v 互为邻接顶点
  • 两个顶点之间有一条有向边,则称两个顶点相邻

子图 Subgraph

  • 设有两个图G=(V, E) 和G'=(V', E')。若V'≤ V 且E≤'E, 则称图G'是图G的子图

图论的简单知识结构

权 Weights

  • 某些图的边具有与它相关的数, 称之为。这种带权图叫做网络

顶点的度 (degrees of the vertices)

  • 一个顶点v的度是与它相关联的边的条数。记作TD(v)。
  • 在有向图中, 顶点的度等于该顶点的入度(in-degree)出度(out-degree)之和
  • 顶点 v 的入度是以 v 为终点的有向边的条数, 记作 ID(v)
  • 顶点 v 的出度是以 v 为始点的有向边的条数, 记作 OD(v)

路径 Path

  • 在图 G=(V, E) 中, 若从顶点 vi 出发, 沿一些边经过一些顶点 vp1, vp2, …, vpm,到达顶点vj。则称顶点序列 (vi vp1 vp2 ... vpm vj) 为从顶点vi 到顶点 vj 的路径。它经过的边(vi, vp1)、(vp1, vp2)、...、(vpm, vj) 应是属于E的边。 ###路径长度
  • 非带权图的路径长度是指此路径上边的条数。
  • 带权图的路径长度是指路径上各边的权之和。 ###简单路径
  • 若路径上各顶点 v1, v2, ..., vm 均不 互相重复, 则称这样的路径为简单路径 ###回路 loop
  • 若路径上第一个顶点 v1 与最后一个顶点vm 重合, 则称这样的路径为回路或环

图论的简单知识结构


连通图与连通分量

  • 在无向图中, 若从顶点v1到顶点v2有路径, 则称顶点v1与v2**连通**。
  • 如果图中任意一对顶点都是连通的, 则称此图是连通图
  • 非连通图的极大连通子图叫做连通分量

强连通图与强连通分量

  • 在有向图中, 若对于每一对顶点vi和vj, 都存在一条从vi到vj和从vj到vi的路径, 则称此图是强连通图。(任意两个顶点相互可达)
  • 非强连通图的极大强连通子图叫做强连通分量

生成树(Spaning tree)

  • 一个连通图的生成树是其极小连通子图,在 n 个顶点的情形下,有 n-1 条边。

图的基本知识就到这里了,如果有必要可以继续往下看。


特别注意的点

悬挂点

  • 度数为1的点为悬挂点,与之相关联的边称为悬挂边。

握手定理

  • 所有顶点的度数等于边数的两倍
  • 在任何顶点中,奇度顶点的个数是偶数 (为什么?)

欧拉图

  • a = 通过图中所有边有且仅有一次行遍所有顶点的通路,称为欧拉通路
  • b = 通过图中所有边有且仅有一次行遍所有顶点的回路,称为欧拉回路
  • a && b为欧拉图, a && ~b为半欧拉图

无向图是欧拉图当且仅当G是连通图且没有奇度顶点

  • 证明比较难讲,但是想起来很好想,如果有了奇度顶点,出去怎么回来?

相关文献:哥尼斯堡七桥问题

  • 有向图G是半欧拉图的条件是G是连通的且恰有两个奇度顶点
  • 有向图D是欧拉图的条件是 当且仅当D是强联通的且每个顶点的入度 == 出度

哈密顿图

  • a = 通过图中所有顶点一次且仅一次的通路称为哈密顿通路
  • b = 通过图中所有顶点一。。。。。。。。。回路称为哈密顿回路
  • 平凡图属于哈密顿图。

  • 树也是图。树是什么样的图?顶点为n,边数为n-1的图

空图
  • 顶点集为空的图,定义为空图
孤立点
  • 没有关联边的顶点称为孤立点

图的表示方法 C语言

邻接矩阵(Adjacency Matrix)


逻辑结构

  • 在图的邻接矩阵表示中,有一个记录各个顶点信息的顶点表,还有一个表示各个顶点之间关系的邻接矩阵。
  • 设图 A = (V, E) 是一个有 n 个顶点的图, 图的邻接矩阵是一个二维数组 A.edge[n][n],定义 图论的简单知识结构图论的简单知识结构图论的简单知识结构

存储结构

  • 最简单的形式就是使用一个二维数组来存储,由于太过简单,这里就不展示了。

邻接表


逻辑结构

  • 邻接表是邻接矩阵的改进形式。为此需要把邻接矩阵的各行分别组织为一个单链表。
  • 在邻接表中,同一个顶点发出的边链接在同一个边链表中,每一个链结点代表一条边(边结点),结点中有另一顶点的下标 dest 和指针 link。对于带权图,边结点中还要保存该边的权值cost。
  • 顶点表的第 i 个顶点中保存该顶点的数据,以及它对应边链表的头指针adj。
  • 你联想到了什么? 图论的简单知识结构

存储结构

  • 使用vector来实现,或者使用new开辟新的数组
  • code
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;

//If G is a tree
//half of n is enough;

#define MAXN 1000
// N 为节点个数
typedef vector <int> vint;
vector <vint> G(MAXN);
//遍历使用clear()函数, 清空使用的空间

void Insert(int a, int i)
{
    G[a].push_back(i);
}

void DFS(int v)
{
    for(int i = 0; i < G[v].size(); i++)
        DFS(G[v][i]);
}

int main()
{
    G.clear();
    return 0;
}

存边的写法,类似于哈希表中的拉链法


struct Arc
{
    int next_arc;
    int point;
};

#define MAXN 1000
#define MAXE 1000

int node[MAXN];
Arc arc[E];

//  以u开始,以v结束
int EdgeCount = 0;;
void AddEdge(int u, int v)
{
    arc[EdgeCount].next_arc = node[u];
    arc[EdgeCount].point = v;
    node[u] = EdgeCount;
    EdgeCount++;
}