图的基本概念,图的遍历、拯救007

图(graph):
表示“多对多”的关系
六度空间理论(Six Degrees Separation)
包含:
1.一组顶点:通常用V(Vertex)表示顶点集合
2.一组边:通常用E(edge)表示边的集合
边是顶点对:(v, w) 属于E, v , w 属于V
有向边<v, w>表示v 指向w的边(单行线)
不考虑重边和自回路

抽象数据类型定义:
1.类型名称:图
2.数据对象集:G(V, E)由一个非空的有限顶点集合v 和一个有限边集合Ezucheng
2.操作集:

常见术语:
有向图:边是有方向的,可能是单向或双向
无向图:边没有方向
带权重的图叫“网络”

怎么在程序中表示一个图:
1.邻接矩阵G[N][N] --- N个顶点从0到N-1编号
1 若<Vi, Vj>是G中的边
G[i][j] = 0 否则

对角元都是0 因为不允许自回路
所有点关于对角线对称(实际上我们把一条边存了两次)
问题:对于无向图的存储,怎样可以省一半空间?
用一个长度N(N+1)/2的一维数组A来存储这些元素Gij在A中的下标是:
(i*(i + 1) / 2 + j)
对于网络,只要把G[i][j]的值定义为边<Vi, Vj>的权重即可
若Vi和Vj之间没有边,则暂用0表示

用邻接矩阵表示一个图的好处:
1.直观、简单、好理解
2.方便检查任意一对顶点间是否存在边
3.方便找任一顶点的“邻接点”(有边直接相连的顶点)
4.方便计算任一顶点的度:(从该顶点发出的边的边数为“出度”, 指向该点的边的边数为“入度”
无向图:对应行(或列)非0元素的个数(也就是所有边的条数)
有向图:对应行非零元素的个数就是“出度”,对应列非零元素的个数就是“入度”

缺点:
1.浪费空间:存稀疏图的时候,点很多,但是边很少,有大量无效元素
对稠密图(特别是完全图)还是很合算的
2.浪费时间: 统计稀疏图中一共有多少条边

用邻接表示一个图:
G[n]为指针数组,对应矩阵每行一个链表,只存非零元素
一定要够稀疏才划算
好处:
1.方便找任一顶点的所有“邻接点”
2.节约稀疏图的空间(需要N个头指针, + 2E个结点(每个结点至少2个域)
3.方便计算任一顶点的度?
对于无向图:是的
对于有向图:只能计算“出度”, 需要构造“逆邻接表”(存指向自己的边,邻接矩阵的一列)
方便计算“入度”
不方便检查任意一对顶点间是否存在边

5.2 图的遍历
1.深度优先搜索(Depth Firsh Search, DFS)
伪代码:(走一步,看一步,走不通后返回到上一个能走通的结点)

类似于树的先序遍历:

void DFS(Vertex V)
{
    visited[V] = true;
    for(V  的每个邻接点 w)
        if(!visited[w])
            DFS(w);
}

若有N个顶点,E条边,时间复杂度是
用邻接表存储图:有O(N+E)
用邻接矩阵存储图:有O(N^2)

2.广度优先搜索(Breadth First Search, BFs)(感觉上应该和邻接表存储搭配更好,但是感觉邻接矩阵也应该合格搭配更好)
(个人感觉用这种遍历方式更好一些)
相当于树的层序遍历(计划性非常强,出队一个,访问一圈,访问的同时入队)

 1 void BFS(Vertex V)
 2 {
 3     visited[V] = true;
 4     EnQueue(V, Q);
 5     while(!IsEmpty(Q))
 6     {
 7         V = DeQueue(Q);
 8         for(V 的每个邻接点 w)
 9             if(!visited[w])
10             {
11                 vitsit[w] = true;
12                 EnQueue(w, Q);
13             }
14     }
15 }

若有N个顶点,E条边,时间复杂度是
用邻接表存储图:有O(N + E)
用邻接矩阵存储图: 有O(N^2)

每调用一次DFS(V)或BFS(V),就把V所在的强连通分量遍历了一遍。

图不连通怎么办(可能有一些孤立的点,他们和其他的结点都不连通)
连通:如果从v 到w存在一条(无向)路径,则称v和w是连通的
路径:v到w的路径是一系列顶点的集合,其中任意一对相邻的顶点间都有图中的边。
路径的长度:是路径中的边数(如果带权,则是所有边的权重和)。如果v和w之间的所有顶点都不同,则称简单路径
回路:起点等于终点的路径
连通图:图中任意两顶点都连通

对于不连通图:
连通分量:无向图的极大连通子图
极大顶点数:再加一个顶点就不连通了
极大边数:包含子图中所有顶点相连的所有边

强连通:有向图中顶点v和w之间存在双向路劲,则称v和w是强连通的
强连通图:有向图中任意两顶点均强连通
弱连通图:不符合强连通图的条件,但是若是将边的方向都去掉,如果是连通的,则称为弱连通图
强连通分量:有向图的极大强连通子图

图不连通时的遍历方法:

1 伪代码:
2 void ListComponents(Graph G)
3 {
4     for(each V in G)
5         if(!visited[V])
6             DFS(V);         //or BFS(V)
7 }

拯救007

void ListComponents(Graph G)
{
    for(each V in G)
        if(!visited[v])
            DFS(V);
}
 1 void Save007 (Graph G)
 2 {
 3     for(each V in G)
 4         if(!visited[V] && FirstJump(V)
 5         {
 6             answer = DFS(V);
 7             if(answer == Yes)
 8                 break;
 9         }
10     if(answer == Yes) output("Yes");
11     else output("No"):
12 }
 1 DFS 算法

2 int DFS(Vertex V)
 3 {
 4     visited[V] = true;
 5     if(IsSave(v)) answer = Yes;
 6     else {
 7         for(each w in G)
 8             if(!visited[w] && Jump(v, w)
 9             {
10                 answer = DFS[w];
11                 if(answer == yes)
12                     break;
13             }
14     }
15     return answer;
16 }

原文地址:https://www.cnblogs.com/hi3254014978/p/9535276.html

时间: 2024-10-09 23:52:23

图的基本概念,图的遍历、拯救007的相关文章

数据结构--图(上)--应用实例:拯救007+六度空间

应用实例:拯救007 总体算法 应用实例:六度空间

浅析数据结构-图的基本概念

线性表和树两类数据结构,线性表中的元素是“一对一”的关系,树中的元素是“一对多”的关系,本章所述的图结构中的元素则是“多对多”的关系.图(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的. 一.图的定义与术语 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合. 1.图的分类 图是按照无方向和有方向分为无向

数据结构-图之基本概念

在图中的数据元素称为顶点(Vertex).顶点之间的关系称为边(Edge).图G是由顶点的有穷集合V,以及边的集合E组成. 由有序对构成的图为有向图(Digraph).在有向图中,两个顶点之间的由弧(Arc)连接,起始点(Initial node)为弧尾(Tail),终止点(terminal node)为弧首(Head). 由无序对构成的图是无向图(Undigraph).无向图的一条边相当于有向图的中两条边,即如果无向图的顶点v1和v2之间有一条边,那么既有从v1连接到v2的边,也有从v2连接到

《UML精粹》第三章 -类图的基本概念

第三章 类图:基本概念 类图可用来描述系统中各种对象的类型,也可描绘出对象间各种各样的静态关系.此外,类图中也可以秀出类的性质(property)与操作(operation),以及可应用到对象间连接方式的一些限制(constraint).在UML中,我们用特性(feature)来代表累的性质与操作这两种概念. 1.性质 性质代表类的结构特性(structural feature).虽然只是一个概念,不过它却可以用两种非常不同的表示法来呈现:属性与关联. 2.属性 属性(attributes)表示

数据结构之图的基本概念

一 图的定义 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合. 在图中需要注意的是: (1)线性表中我们把数据元素叫元素,树中将数据元素叫结点,在图中数据元素,我们则称之为顶点(Vertex). (2)线性表可以没有元素,称为空表:树中可以没有节点,称为空树:但是,在图中不允许没有顶点(有穷非空性). (3)线性表中的各元素是线性关系,树中的各元素是层次关系,而图中各顶点的关系是用边来表示

图的表示、深度广度遍历算法及其应用

世间的一切对象都可化为节点:世间一切关系都可化为节点间的一条线:从而组成了如梦幻泡影的图.将来的环球必定是图的世界. 一.图的表示 图有有向图和无向图,表示方法一般有邻接表.邻接矩阵等方法,无向图和有向图都可以用这两种方法表示. 图1. 图的例子[1] 1.邻接表 在邻接表中,对于每个顶点u,使用一个链表把所有与u相邻的点点串起来,并标记这个集合为adj(u).举个栗子如下: 图2. 邻接表表示图的例子[1] 在真正操作图进行实验的时候,一般也都使用邻接矩阵表示,例如要存储图1中的有向图,可以直

图、图的存储、图的遍历

图(Graph)是由顶点的有穷非空集合和顶点之间的边组成.G(V,E) V表示顶点的集合,E表示边的集合. 在无向图中,边可以表示为E1={(A,D),(B,C)} 在有向图中,顶点v1和v2的有向边称为弧.表示为<v1,v2> v1称为弧尾,v2称为弧顶. 在无向图中,如果任意边两个顶点都存在边,则该图为无向完全图,n个顶点的无向完全图有n*(n-1)/2条边. 在有向图中,如果任意边两个顶点都存在互为相反边,则该图为有向完全图,n个顶点的有向完全图有n*(n-1)条边. 稀疏图,稠密图.

1.1图的基本概念

(参考书籍:2018数据结构 王道考研) 图的定义 图G由定点集V和边集E组成 记为G=(V,E) 其中V(G)为G中顶点的有限非空集 E(G)为G中边(顶点关系)集和 |V|表示G中顶点个数,也称为图的阶 E={ (u , v) | u, v 均为顶点 } |E|表示G中边的条数 注意:图不能为空,边可以为空,但顶点一定非空 有向图 若E为有方向的边(也称为弧),此时图为有向图 记做<u,v > u为弧头 v为弧尾,称为u到v的弧.u邻接到v的弧.v邻接自u的弧 G = (E , V) E

数据结构之图(一)图的存储结构

图的存储结构相对于线性表和树来说更为复杂,因为图中的顶点具有相对概念,没有固定的位置.那我们怎么存储图的数据结构呢?我们知道,图是由(V, E)来表示的,对于无向图来说,其中 V = (v0, v1, ... , vn),E = { (vi,vj) (0 <=  i, j <=  n且i 不等于j)},对于有向图,E = { < vi,vj > (0 <=  i, j <=  n且i 不等于j)}.V是顶点的集合,E是边的集合.所以我们只要把顶点和边的集合储存起来,那么