C++数据结构_图的理论学习笔记(1)_基本概念、存储结构

1.1 基本概念

1.1.1 图的定义

        图G由两个集合V和E构成,记作G(V, E),其中,V代表图中顶点的集合,E代表顶点之间的关系。E可以是空集,表示图只有顶点而没有边。
        (v1,v2)表示v1和v2之间有一条边(无方向);<v1,v2>表示v1和v2之间有一条弧(有方向)。图的表示方法示例如下图:
在这里插入图片描述
        (a)图的表示方法为:V={v1, v2, v3, v4, v5}、E={(v1, v2),(v1, v4),(v2, v3),(v2, v5),(v3,v4),(v3,v5)};
        (b)图的表示方法为:V={v1,v2,v3,v4},E={<v1,v2>,<v1,v3>,<v3,v4>,<v4,v1>}

1.1.2 图的基本术语

        1.顶点:数据元素常称为顶点;
        2.边:顶点之间的无向连线;
        3.弧:顶点之间的有向连线;
        4.无向图:图中的每条连线都无方向,如下图(a)所示;
        5.有向图:图中的每条连线都有方向,如下图(b)所示;
        6.简单图:不存在顶点到其自身的边,且同一条边不重复。下图(c)(d)都不是简单图;
        7.邻接点:若(vi,vj)是图中的一条边,则vi,vj互为邻接点;若<vi,vj>是图中的一条弧,则vj是vi的邻接点;
        8.如下图(e)所示,含有n个顶点,n(n-1)/2条边的图称为完全无向图;如下图(f)所示,含有n个顶点,n(n-1)条弧的图称为完全有向图;
        9.边或弧很少的图成为稀疏图,边或弧较多的图称为稠密图。这是相对而言的概念。如下图(g)与(h)相比,(g)是稀疏图,(h)是稠密图;
在这里插入图片描述
        10.度:一个顶点的度是与他相关联的边或弧的条数;
        11.入度:有向图中到达顶点的弧数,下图A的入度为1;
        12.出度:有向图中顶点出发的弧数,下图A的出度为2;
在这里插入图片描述
        13.网:带权的图,如下图所示,根据网是否有向可以分为有向网和无向网;
在这里插入图片描述
        14.图的子集,如下图所示;
在这里插入图片描述
        15.路径:接续的边的端点构成的顶点序列;
        16.路径长度:路径上边或弧的数目;在网中为路径上边或弧的权值之和;下图中v1到v5的路径(v1,v4,v3,v5)的长度为3;
在这里插入图片描述
        17.回路:起点和终点相同的路径;
        18.简单路径:路径序列中顶点不重复出现的路径,如下图(a)所示;
        19.简单回路:路径序列中,除了起点和终点外其余顶点均不相同,如下图(c)所示;
在这里插入图片描述
        20.连通图:在无向图中,若任意一对顶点都存在路径,则称其为连通图,否则为非连通图;
        21.连通分量:无向图中的极大连通子图。极大连通子图包含所有联通的顶点以及和这些顶点相关联的所有边,如下图所示;
在这里插入图片描述
        22.强连通图:在有向图中,若任意一对顶点都存在路径,则称其为强连通图,否则为非强连通图;
        23.强连通分量:有向图中的最大连通子图,如下图所示;
在这里插入图片描述
        24.生成树:连通图中一个极小连通子图,即含有全部顶点,但只有足以构成树的n-1条边,如下图所示;
在这里插入图片描述
        25.生成森林:在非连通图中,每一个连通分量都可以得到一颗生成树,这些连通分量的生成树构成生成森林,如下图所示;
在这里插入图片描述

1.2 图的存储结构

        图是一种复杂的非线性结构。数据结构中的逻辑结构有集合、线性结构、树结构和图结构。
        一个图包括两部分信息:即顶点与顶点之间的关系。

1.2.1 邻接矩阵

        二维数组可以用来表示其顶点之间的相邻关系。设G=(V, E)是有n个顶点的图,其序号分别为0,1,2…其邻接矩阵表示为:
在这里插入图片描述
        无向图的邻接矩阵一定为对称矩阵,有向图的邻接矩阵可以不对称,如下图所示:
在这里插入图片描述
        网的邻接矩阵可以定义为:
在这里插入图片描述
在这里插入图片描述
        用邻接矩阵表示法,除了存储用于表示顶点间相邻关系的邻接矩阵外,通常还要用一个顺序表来存储顶点信息,其C++描述如下:

const int MAXSIZE = 10;
template<class T> class MGraph
{
public:
	MGraph(ifstream& fin); // 构造函数
	void DFS(int v); // 从v出发深度优先
	void BFS(int v); // 从v出发广度优先
private:
	T vertex[MAXSIZE]; // 顶点
	int arc[MAXSIZE][MAXSIZE]; //弧
	int vNum, arcNum; // 顶点数,边数
};

1.2.2 邻接表

        邻接表表示法类似于树的孩子链表表书法,是一种顺序结构和链式结构相结合的存储方法,如下图所示:
在这里插入图片描述
        邻接表的存储结构中有两种结点结构:顶点结点VertexNode和弧结点ArcNode,如下图所示。
在这里插入图片描述
        邻接表顶点和弧结点的C++描述如下:

struct VertexNode
{
	char vertex; // 数据域:顶点信息
	ArcNode* firstarc; // 指针域:指向第一条弧
};

struct ArcNode 
{
	int adjvex; // 数据域:邻接顶点下标
	ArcNode* nextarc; // 指针域:指向下一条弧结点
};

        储存无向图时,每一条边都相当于两条弧,如下图所示:
在这里插入图片描述
        若采用邻接表存储无向网,那么每条弧还需要存储边权值,如下图所示:
在这里插入图片描述
        有向图还有一种表示方法为逆邻接表表示法,该方法为图中每个顶点建立一个入边表,入边表中每个表结点均对应一条以该节点为终点的边,如下图所示:
在这里插入图片描述
        C++描述如下:

const int MAXSIZE = 10;
template<class T> class ALGraph
{
public:
	ALraph(ifstream& fin); // 构造函数
	~ALGraph();
	void DFS(int v); // 深度优先遍历
	void BFS(int v); // 广度优先遍历
private:
	VertiexNode adjlist[MAXSIZE]; // 结点
	int vNum, arcNum; // 顶点数,弧数
};

1.2.3 十字链表

        下图是一个十字链表的示例:
在这里插入图片描述
        在十字链表中可以很容易找到以某结点为弧头的弧,也很容易找到以某结点为弧尾的弧,因为很容易求得每个结点的出度和入度。

1.2.4 邻接多重表

        下图是一个邻接多重表的示例:
在这里插入图片描述
        用邻接表存储无向图,其每条边的两个顶点分别在该边所依附的两个顶点边表中。这种重复存储在某些操作时十分不便,例如在对已访问过的边做标记,或者要删除图中某一条边时,都需要找到表示同一条边的两个边表结点,这时使用邻接多重表更适宜。

1.2.5 边集数组

        利用两个一维数组,其中一个数组存储图中的顶点,另一个数组存储图中的边,如下图所示:
在这里插入图片描述
        边集数组中查找一条边或求顶点的度需要扫描整个边数组,时间复杂度为O(e),空间复杂度为O(n+e)。因此,边集数组适合表示稀疏图

1.2.6 图的存储结构比较

        就空间复杂度而言,采用邻接矩阵需要O(n2)个单位的存储空间,而采用邻接表,则需要O(n+e)个单位的存储空间。哪种表示方法的存储效率高取决于图中边的数目。一般情况下,图越稠密,邻接矩阵的空间效率相应地越高,而对稀疏图使用邻接表存储,则能获得较高的空间效率。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值