目录

  • 一、图的定义和基本术语(Graph)
    • (一)图的定义
    • (二)图的基本术语
  • 一、图的存储结构
    • (一)邻接矩阵(Adjacency Matrix)
      • 1、无向图的邻接矩阵
      • 2、有向图的邻接矩阵
      • 3、网(即有权图)的邻接矩阵
      • 4、邻接矩阵的存储表示
      • 5、采用邻接矩阵表示法创建无向网
    • (二)邻接表(链式)表示法(Adjacency List)
      • 1、无向图的邻接表表示
      • 2、有向图的邻接表表示
      • 3、图的邻接表的存储定义
      • 4、采用邻接表表示法创建无向图
      • 5、邻接矩阵与邻接表的比较
    • (三)十字链表(Orthogonal List)
      • 1、弧结点的结构
      • 2、顶点结点的结构
      • 3、图的结构定义
      • 4、实例
      • 5、有向图G的十字链表
    • (四)邻接多重表(Adjacent MultiList)
      • 1、边结点的结构
      • 2、顶点结点的结构
      • 3、图的结构定义
      • 4、实例
      • 4、练习:画出无向图G的邻接多重表

一、图的定义和基本术语(Graph)

(一)图的定义

图(Graph)是由一个顶点集V和一个边集E构成的数据结构。
G=(V,E)
V:顶点(数据元素)的又穷非空集合
E:边的又穷集合

无向图:每条边都是没有方向的
有向图:每条边都是有方向的,边也称作弧

(二)图的基本术语

设n表示图中顶点的数目,e表示边的数目
完全图:任意两个点都有一条边相连

稀疏图:如果边或者弧的个数满足e<n*log2n,则称作稀疏图,否则称作稠密图


对无向图来说:
邻接点:若顶点v和顶点w之间存在一条边a,则称顶点v和w互为邻接点。边a与顶点v和w相关联。
度:与顶点v关联的边的数目,记为TD(v)

对有向图来说:
1、<x,y>为有向边(弧),x为有向边的起点(弧尾),y为有向边的终点(弧头)
2、顶点v的入度是以v为终点的有向边的条数,记作ID(v)
3、顶点v的出度是以v为始点的有向边的条数,记作OD(v)

路径:连续的边构成的顶点序列
路径长度:路径上边或者弧的数目
简单路径:除路径起点和终点可以相同外,其余顶点均不相同的路径
简单回路(简单环):除路径起点和终点相同外,其余顶点均不相同的路径。


一、图的存储结构

图的存储表示特点:
1、图没有顺序存储结构,但可以借助二维数组来表示图的元素之间的关系
2、以顶点为核心,建立邻接点和弧的关系;

(一)邻接矩阵(Adjacency Matrix)

1、考虑到图是由两个顶点和边或弧两部分组成,合在一起比较困难,可以分为两个结构来存储
2、顶点因为不区分大小,主次,所以可以用一个一维数组来存储,记录各个顶点的信息
3、边或弧是顶点和顶点的关系,用邻接矩阵来存储,表示各个顶点之间的邻接关系。

1、无向图的邻接矩阵

2、有向图的邻接矩阵

3、网(即有权图)的邻接矩阵

4、邻接矩阵的存储表示

/*图的邻接矩阵存储表示法*/
//用两个数组分别存储顶点表和邻接矩阵
#define MaxInt 32767  //表示极大值,即无穷
#define MVNum 100  //最大顶点数
typedef char VerTexType;  //假设顶点的数据类型为字符型
typedef int ArcType;    //假设边的权值类型为整型
typedef struct
{VerTexType vexs[MVNum];    //顶点表ArcType arcs[MVNum][MVNum];    //邻接矩阵int vexnum, arcnum;   //图的当前顶点数和边数
}AMGraph;

5、采用邻接矩阵表示法创建无向网

【算法步骤】
1、输入总顶点数和边数
2、依次输入点的信息存入到顶点表中
3、初始化邻接矩阵,使每个权值初始化为极大值
4、构造邻接矩阵

注意:
1、无向图需要为arcs[i][j]和arcs[j][i]赋值
2、有向图仅需为arcs[i][j]赋值

算法描述:

/*采用邻接矩阵表示法创建无向网*/
Status CreateUDN(AMGraph& G)
{cin >> G.vexnum >> G.arcnum;//输入总顶点数和总边数for (int i = 0;i < G.vexnum;++i)cin >> G.vexs[i];//依次输入顶点的信息for (int i = 0;i < G.vexnum;++i)//初始化邻接矩阵,边的权值均置为极大值for (int j = 0;j < G.vexnum;++j)G.arcs[i][j] = MaxInt;for (int k = 0;k < G.arcnum;++k){cin >> v1 >> v2 >> w;//输入一条边依附的顶点和权值i = LocateVex(G, v1);j = LocateVex(G, v2);//确定两个顶点v1和v2在G中的位置G.arcs[i][j] = w;//边<v1,v2>的权值置为wG.arcs[j][i] = G.arcs[i][j];//置边<v1,v2>的对称点<v2,v1>的权值也为w}return OK;
}
/*在图中查找顶点的位置LocateVex()函数*/
int LocateVex(AMGraph G, VertexType u)
{//若在图中找到这个元素,则返回它的下标i,否则返回-1int i;for (i = 0;i < G.vexnum;++i)if (u == G.vexs[i])return i;return -1;
}

(二)邻接表(链式)表示法(Adjacency List)

是图的链式存储结构,基本思想就是只存储图中存在的边的信息,对不相邻的顶点则不保留信息
对图中每个顶点vi建立一个带头结点的单链表,把与vi相邻接的顶点放在这个链表中,一个单链表对应邻接矩阵中的一行,称为边链表。

1、无向图的邻接表表示

2、有向图的邻接表表示

3、图的邻接表的存储定义

分三部分:
1、图的结构定义
2、顶点的头结点结构
3、弧(边)的结点结构

/*图的邻接表的存储定义*/
//弧的结点结构
#define MVNum 100   //最大的顶点数
typedef struct ArcNode
{int adjvex;    //该边所指的顶点的位置struct ArcNode* nextarc;    //指向下一条边的指针OtherInfo info;  //和边相关的信息
}ArcNode;
//顶点的结点结构
typedef struct VNode
{VertexType data;//顶点信息ArcNode* firstarc;//指向第一条依附该顶点的边
}VNode,AdjList[MVNum];//AdjList表示邻接表类型
//AdjList v相当于VNode v[MVNum]//图的结构定义(邻接表)
typedef struct
{AdjList vertices;//vertices是vertex的复数int vexnum, arcnum;//图的当前顶点数和边数
}ALGraph;/*说明*/
ALGraph G;//定义了邻接表表示的图G
G.vexnum = 5;G.arcnum = 6;//图G包含了5个顶点和6条边
G.vertices[1].data = 'v2';//图G中第2个顶点是v2
p = G.vertices[1].firstarc;//指针p指向顶点v2的第一个边结点
p->adjvex = 4;//p指针所指边结点是到下标为4的结点的边

4、采用邻接表表示法创建无向图

【算法步骤】
1、输入总顶点数和总边数
2、建立顶点表

1、依次输入点的信息存入顶点表中
2、使每个表头结点的指针域初始化为NULL

3、创建邻接表

1、依次输入每条边依附的两个顶点
2、确定这两个顶点的序号i和j
3、将此边结点分别插入vi和vj对应的两个边链表的头部

/*采用邻接表表示法创建无向图*/
Status CreateUDG(ALGraph& G)
{//采用邻接表表示法,创建无向图Gcin >> G.vexnum >> G.arcnum;//输入顶点数和弧数for (int i = 0;i < G.vexnum;++i){cin >> G.vertices[i].data;//输入顶点值G.vertices[i].firstarc = NULL;//初始化表头结点的指针域为NULL}for (int k = 0;k < G.arcnum;++k)//输入各边,构造邻接表,头插法{cin >> v1 >> v2;//输入一条边依附的两个顶点i = LocateVex(G, v1);j = LocateVex(G.v2);p1 = new ArcNode;//生成一个新的边结点*p1p1->adjvex = j;//邻结点序号为jp1->nextarc = G.vertices[i].firstarc;//firstarc为空,所以nextarc也指向空,即最后的一个结点G.vertices[i].firstarc = p1;//将新结点*p1插入到顶点vi的边表头部p2 = new ArcNode;//生成一个新的边结点*p2p2->adjvex = i;p2->nextarc = G.vertices[j].firstarc;//插入弧结点到单链表G.vertices[j].firstarc = p2;//将新结点*p2插入到顶点vi的边表头部}//头插法return OK;
}

5、邻接矩阵与邻接表的比较


练习:画出有向图G的邻接矩阵、邻接表、逆邻接表

(三)十字链表(Orthogonal List)

十字链表是有向图的另一种链式存储结构,可以看成是将有向图的邻接表和逆邻接表结合起来得到的一种链表

1、弧结点的结构


Tailvex:指示弧尾结点在图中的位置
headtex:指示弧头顶点在图中的位置
hlink:是指向弧头相同的下一条弧的指针
tlink:是指向弧尾相同的下一条弧的指针
Info:指向该弧的相关信息

/*弧结点的结构*/
typedef struct ArcBox
{int tailvex, headvex;//该弧的尾和头顶点的位置struct ArcBox* hlink, * tlink;//分别为弧头相同和弧尾相同的弧的指针域InfoType* info;//该弧相关信息的指针
}ArcBox;

2、顶点结点的结构


每个顶点有一个结点,它相当于出边表和入边表的表头结点。数据成员data存放与该顶点的相关信息。链域firstin指示以该顶点为弧头的第一个弧结点。链域firstout指示以该结点为弧尾的第一个弧结点。

/*顶点结点的结构*/
typedef struct VexNode
{VertexType data;ArcBox* firstin, * firstout;//分别指向该顶点第一条入弧和出弧
}VexNode;
//ArcBox为弧结点变量

3、图的结构定义

/*图的结构定义*/
typedef struct
{VexNode xlist[MAX_VERTEX_NUM];//表头向量int vexnum, arcnum;//有向图的当前顶点数和弧数
}OLGraph;

4、实例

5、有向图G的十字链表

(四)邻接多重表(Adjacent MultiList)

邻接多重表是无向图的另一种链式存储结构,由于用邻接表存储无向图时,虽然容易求出顶点和边的各种信息,但在邻接表中每一条边有两个结点,分别在第i和j个链表中,给图的某些操作带来不便,在邻接多重表中,每一条边只有一个边结点,为有关的处理提供了方便。

1、边结点的结构

mark:为标志域,可用以标记该条边是否被搜索过
ivex和jvex为该边依附的两个顶点在图中的位置
ilink:指向下一条依附于顶点的ivex的边
jlink:指向下一条依附于顶点jvex的边
info:为指向和边相关的各种信息个指针域

/*边结点结构*/
typedef struct EBox
{VisitIf mark;//访问标志域int ivex, jvex;//该边依附的两个顶点在表头数组中的位置struct Ebox* ilink, * jlink;//分别指向依附于ivex和jvex的下一条边InfoType* info;
}EBox;

2、顶点结点的结构

/*顶点结点的结构*/
typedef struct VexBox
{VertexType data;//存与顶点相关的信息EBox* firstedge;//指向第一条依附于该顶点的边
}VexBox;

3、图的结构定义

/*图的结构定义*/
typedef struct
{VexBox adjmulist[MAX_VERTEX_NUM];//表头向量int vexnum, edgenum;//无向图的当前顶点数和弧数
}OLGraph;
//VexNode为顶点结点变量

4、实例

4、练习:画出无向图G的邻接多重表

【数据结构——图和图的存储结构】相关推荐

  1. 图的数组(邻接矩阵)存储结构

    图是比较复杂的数据结构,它由顶点和顶点之间的弧或边组成.任何两个顶点之间都 可能存在弧或边.在计算机存储图时,只要能表示出顶点的个数及每个顶点的特征.每对 顶点之间是否存在弧(边)及弧(边)的特征,就 ...

  2. 图的链式存储结构解析(邻接表、逆邻接表、十字链表、邻接多重表)

    图的矩阵表示法比较消耗空间,需要花费$ n 2 n^2 n2$个单元存储边(弧).在边数较少的情况下比较浪费.我们这里来讨论图的链式存储结构. 图的链式结构主要有四类:邻接表.逆邻接表.十字链表.邻接 ...

  3. 图的几种存储结构与方法(有向图+无向图)

    图的几种存储结构: 1.邻接矩阵 2.链式前向星 3.C++中vector的邻接表 (一)邻接矩阵 邻接矩阵是表示顶点之间相邻关系的矩阵. 基本思想为: S[i][j]S[i][j]S[i][j] 就 ...

  4. 数据结构考研:数据结构的三要素:逻辑结构,存储结构,数据计算的详细区分与讲解(软件工程/计算机/王道论坛)

    一.问题背景 不管是计算机专业的考研初试还是工作面试,数据结构都是很重要的课程.而博主最近看的王道论坛2020的数据结构开篇就有数据结构的三要素:逻辑结构,存储结构,数据计算,而在数据结构的考研真题和 ...

  5. mysql 邻接表_图的邻接表存储结构详解

    通常,图更多的是采用链表存储,具体的存储方法有 3 种,分别是邻接表.邻接多重表和十字链表. 本节先讲解图的邻接表存储法.邻接表既适用于存储无向图,也适用于存储有向图. 在具体讲解邻接表存储图的实现方 ...

  6. 图的十字链表存储结构

    前面介绍了图的邻接表存储法,本节继续讲解图的另一种链式存储结构--十字链表法. 与邻接表不同,十字链表法仅适用于存储有向图和有向网.不仅如此,十字链表法还改善了邻接表计算图中顶点入度的问题. 十字链表 ...

  7. 数据结构概述(逻辑结构与存储结构概念详解)

    目录 一.一些基本概念 二.逻辑结构 1.集合结构: 2.线性结构: 1)线性表: 2)栈 3)队列 4)串 3.非线性结构: 1)数组 2)广义表 3)树 4)堆 5)图 三.物理结构/存储结构 1 ...

  8. 数据结构之二叉树,二叉树存储结构,二叉树遍历,霍夫曼树以及图解

    数据结构之二叉树 树 什么是树? 树是一种一对多的数据结构.树有很多子集,比如:二叉树.完全二叉树.满二叉树.二叉搜索树等等. 树的特征: 没有父结点的叫做根,一个树有且只有一个根: 每个结点有0个或 ...

  9. 【数据结构】广义表的存储结构及基本运算(C语言)

    目录 1. 广义表基本概念 2. 广义表的存储结构 2.1 头尾链表存储结构 2.2 同层结点链存储结构 3. 广义表的基本运算 3.1 求表头.表尾 3.2 求长度.深度 3.3 统计原子数目 3. ...

  10. 数据结构(一)线性存储结构

    一.基本概念 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系. 线性结构拥有两种不同的存储结构,即顺序存储结构和链式存储结构.顺序存储的线性表称为顺序表,顺序表中的存储元素是连 ...

最新文章

  1. UVA1025 城市里的间谍 A Spy in the Metro(2003 ICPC world final)(DAG上DP)
  2. android中实现返回首页功能
  3. spring mvc后端代码实现弹出对话框_Spring(3)——事务管理和MVC
  4. android闹钟的需求分析,手机小闹钟需求分析
  5. [链表]---链表相邻元素翻转
  6. 恋与制作人 服务器错误,恋与制作人安装失败怎么办_恋与制作人安装失败解决方法_游戏吧...
  7. 妇女节放假送礼物 乐视:提倡工作的同时要兼顾家庭生活
  8. java 实现nfa的化简_NFA的实现
  9. DevOps-2-从凤凰项目谈起
  10. (2021.10.25-10.31)小结
  11. 高中计算机课简单介绍,高中课程介绍
  12. 惠普服务器win10安装系统教程,惠普电脑如何重装系统教程 win10专业版系统安装教程...
  13. 蓝桥杯 java 跳马问题
  14. NVIDIA Jetson TK1学习与开发(二):入门指导
  15. 大厂如何开发和部署前端代码?淘宝8年案例解读
  16. 搜图出处的软件_以图搜图搜gif图片出处来源的懒人小工具
  17. 如何将“\”替换为任意字符
  18. 计算机卡怎么解决,电脑卡怎么办,详细教您电脑卡怎么解决
  19. 有没有人拼团csdn学习会员~~
  20. ECharts修改坐标轴,坐标轴字体,坐标轴网格样式

热门文章

  1. 【U8】禁止UU(UTU)随登陆账套启动(U8V11.0及其以上版本)
  2. Unity多人游戏简单实例(一)快速入门
  3. spark shuffle 内幕彻底解密
  4. java毕业设计——基于java+jsp+Servlet的B2C网上拍卖系统设计与实现(毕业论文+程序源码)——网上拍卖系统
  5. Oulipo HDU - 1686--strlen()耗时啊啊啊--KMP
  6. Growth Hacker:新型的市场 VP
  7. Python学习日记-第二十六天-飞机大战(发射子弹和碰撞检测)
  8. 高速服务器有维修站吗,高速公路上服务区有修车的吗?
  9. 51nod2943 旅行者
  10. mysql好评中评统计_scrapy爬取京东笔记本及评论信息存入MySQL数据库