数据结构 图的存储表示
数据结构中的名词解释
数据结构中的名词解释数据结构中的名词解释数据结构:数据结构是研究数据元素之间抽象化的相互关系和这种关系在计算机中的存储表示(即所谓数据的逻辑结构和物理结构),并对这种结构定义相适应的运算,设计出相应的算法,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。
数据:数据是人们利用文字符号、数字符号以及其他规定的符号对现实世界的事物及其活动所做的描述。
在计算机科学中,数据的含义非常广泛,我们把一切能够输入到计算机中并被计算机程序处理的信息,包括文字、表格、图象等,都称为数据。
结点:结点也叫数据元素,它是组成数据的基本单位。
逻辑结构:结点和结点之间的逻辑关系称为数据的逻辑结构。
存储结构:数据在计算机中的存储表示称为数据的存储结构。
数据处理:数据处理是指对数据进行查找、插入、删除、合并、排序、统计以及简单计算等的操作过程。
数据类型:数据类型是指程序设计语言中各变量可取的数据种类。
数据类型是高级程序设计语言中的一个基本概念,它和数据结构的概念密切相关。
本章主要介绍了如下一些基本概念:线性表:一个线性表是n≥0个数据元素a0,a1,a2,…,an-1的有限序列。
线性表的顺序存储结构:在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构。
线性表的链式存储结构:线性表的链式存储结构就是用一组任意的存储单元——结点(可以是不连续的`)存储线性表的数据元素。
表中每一个数据元素,都由存放数据元素值的数据域和存放直接前驱或直接后继结点的地址(指针)的指针域组成。
循环链表:循环链表(Circular Linked List)是将单链表的表中最后一个结点指针指向链表的表头结点,整个链表形成一个环,从表中任一结点出发都可找到表中其他的结循环链表:循环链表(Circular Linked List)是将单链表的表中最后一个结点指针指向链表的表头结点,整个链表形成一个环,从表中任一结点出发都可找到表中其他的结点。
数据结构的逻辑结构、存储结构及数据运算的含义及其相互关系
2007 C C C 语言的特点,简单的C 程序介绍,C 程序的上机步骤。
1 、算法的概念2、简单的算法举例3、算法的特性4、算法的表示(自然语言、流程图、N-S 图表示) 1 、 C 的数据类型、常量与变星、整型数据、实型数据、字符型数据、字符串常量。
2、 C 的运算符运算意义、优先级、结合方向。
3、算术运算符和算术表达式,各类数值型数据间的混合运算。
4、赋值运算符和赋值表达式。
5、逗号运算符和逗号表达式。
1 、程序的三种基本结构。
2、数据输入输出的概念及在C 语言中的实现。
字符数据的输入输出,格式输入与输出。
1 、关系运算符及其优先级,关系运算和关系表达式。
2、逻辑运算符及其优先级,逻辑运算符和逻辑表达式。
3、if语句。
if语句的三种形式,if语句的嵌套,条件运算符。
4、switch 语句. 1 、while 语句。
2、do/while 语句。
3、for 语句。
4、循环的嵌套。
5、break 语句和continue 语句。
1 、一维数组的定义和引用。
2、二维数组的定义和引用。
3、字符数组。
4、字符串与字符数组。
5、字符数组的输入输出。
6、字符串处理函数1 、函数的定义。
2、函数参数和函数的值,形式参数和实际参数。
3、函数的返回值。
4、函数调用的方式,函数的声明和函数原型。
5、函数的嵌套调用。
6、函数的递归调用。
7、数组作为函数参数。
8、局部变量、全局变量的作用域。
9、变量的存储类别,自动变星,静态变量。
1 、带参数的宏定义。
2、“文件包含”处理。
1 、地址和指针的概念。
2、变量的指针和指向变量的指针变量。
3、指针变量的定义和引用。
4、指针变量作为函数参数。
5、数组的指针和指向数组的指针变量。
6、指向数组元素的指针。
7、通过指针引用数组元素。
8、数组名作函数参数。
9、二维数组与指针。
1 0、指向字符串的指针变星。
字符串的指针表示形式,字符串指针作为函数参数。
11 、字符指针变量和字符数组的异同。
数据结构-chap7 (1)图的存储结构
V2
V4 G2图示
无向图:在图G中,若所有边是无向边,则称G为无向图。
有向图:在图G中,若所有边是有向边,则称G为有向图。
二、图的基本术语
有向完全图: n个顶点的有向图最大边数是n(n-1) 无向完全图: n个顶点的无向图最大边数是n(n-1)/2 1、邻接点及关联边
主要内容
知识点
– – – – 1.图的定义,概念、术语及基本操作。 2.图的存储结构,特别是邻接矩阵和邻接表。 3.图的深度优先遍历和宽度优先遍历。 4.图的应用(连通分量,最小生成树,拓扑排序,关键路经,最短 路经)。 1.基本概念中,完全图、连通分量、生成树和邻接点是重点。 2.建立图的各种存储结构的算法。 3.图的遍历算法及其应用。 4.通过遍历求出连通分量的个数,深(宽)度优先生成树。 5.最小生成树的生成过程。 6.拓扑排序的求法。关键路经的求法。 7.最短路径的手工模拟。
自测题 2
设无向图的顶点个数为n,则该图最多有( )条边。 A.n-1
B.n(n-1)/2
C.n(n+1)/2 D.0 E.N2 【清华大学1998一.5(分)】
自测题 3
一个有n个结点的图,最少有( )个连通分量,最多有( )个 连通分量。
A. 0
B.1 C.n-1 D.n 【北京邮电大学 2000 二.5 (20/8分)】
0
V1 e1 V3 V4 V5 V2 1 0 1 0 1
否则
0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 V1 V2 0 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0
数据结构-实验6图的存储和遍历
实验6.1实现图的存储和遍历一,实验目的掌握图的邻接矩阵和邻接表存储以及图的邻接矩阵存储的递归遍历。
二,实验内容6.1实现图的邻接矩阵和邻接表存储编写一个程序,实现图的相关运算,并在此基础上设计一个主程序,完成如下功能:(1)建立如教材图7.9所示的有向图G的邻接矩阵,并输出。
(2)由有向图G的邻接矩阵产生邻接表,并输出。
(3)再由(2)的邻接表产生对应的邻接矩阵,并输出。
6.2 实现图的遍历算法(4)在图G的邻接矩阵存储表示基础上,输出从顶点V1开始的深度优先遍历序列(递归算法)。
(5)利用非递归算法重解任务(4)。
(6)在图G的邻接表存储表示基础上,输出从顶点V1开始的广度优先遍历序列。
三,源代码及结果截图#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream.h>#include<malloc.h>#define MAX_VERTEX_NUM 20typedef char VRType;typedef int InfoType; // 存放网的权值typedef char VertexType; // 字符串类型typedef enum{DG,DN,AG,AN}GraphKind; // {有向图,有向网,无向图,无向网}/*建立有向图的邻接矩阵*/typedef struct ArcCell{VRType adj;//VRType是顶点关系类型,对无权图用1或0表示是否相邻;对带权图则为权值类型InfoType *info; //该弧相关信息的指针(可无)}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs;//邻接矩阵int vexnum,arcnum;;//图的当前顶点数和弧数GraphKind kind;//图的种类标志}MGraph;/* 顶点在顶点向量中的定位*/int LocateVex(MGraph &M,VRType v1){int i;for(i=0;i<M.vexnum;i++)if(v1==M.vexs[i])return i;return -1;}void CreateGraph(MGraph &M)//建立有向图的邻接矩阵{int i,j,k,w;VRType v1,v2;M.kind=DN;printf("构造有向网:\n");printf("\n输入图的顶点数和边数(以空格作为间隔):");scanf("%d%d",&M.vexnum,&M.arcnum);printf("输入%d个顶点的值(字符):",M.vexnum);getchar();for(i=0;i<M.vexnum;i++) //输入顶点向量{scanf("%c",&M.vexs[i]);}printf("建立邻接矩阵:\n");for(i=0;i<M.vexnum;i++)for(j=0;j<M.vexnum;j++){M.arcs[i][j].adj=0;M.arcs[i][j].info=NULL;}printf("请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):\n");for(k=0;k<M.arcnum;++k)// 构造表结点链表{cin>>w>>v1>>v2;i=LocateVex(M,v1);j=LocateVex(M,v2);M.arcs[i][j].adj=w;}}//按邻接矩阵方式输出有向图void PrintGraph(MGraph M){int i,j;printf("\n输出邻接矩阵:\n");for(i=0; i<M.vexnum; i++){printf("%10c",M.vexs[i]);for(j=0; j<M.vexnum; j++)printf("%2d",M.arcs[i][j].adj);printf("\n");}}// 图的邻接表存储表示typedef struct ArcNode{int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc; // 指向下一条弧的指针InfoType *info; // 网的权值指针)}ArcNode; // 表结点typedef struct VNode{VertexType data; // 顶点信息ArcNode *firstarc; // 第一个表结点的地址,指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];// 头结点typedef struct{AdjList vertices;int vexnum,arcnum; // 图的当前顶点数和弧数int kind; // 图的种类标志}ALGraph;void CreateMGtoDN(ALGraph &G,MGraph &M){//由有向图M的邻接矩阵产生邻接表int i,j;ArcNode *p;G.kind=M.kind;G.vexnum=M.vexnum;G.arcnum=M.arcnum;for(i=0;i<G.vexnum;++i){//构造表头向量G.vertices[i].data=M.vexs[i];G.vertices[i].firstarc=NULL;//初始化指针}for(i=0;i<G.vexnum;++i)for(j=0;j<G.vexnum;++j)if(M.arcs[i][j].adj){p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;p->info=M.arcs[i][j].info;G.vertices[i].firstarc=p;}}void CreateDNtoMG(MGraph &M,ALGraph &G){ //由邻接表产生对应的邻接矩阵int i,j;ArcNode *p;M.kind=GraphKind(G.kind);M.vexnum=G.vexnum;M.arcnum=G.arcnum;for(i=0;i<M.vexnum;++i)M.vexs[i]=G.vertices[i].data;for(i=0;i<M.vexnum;++i){p=G.vertices[i].firstarc;while(p){M.arcs[i][p->adjvex].adj=1;p=p->nextarc;}//whilefor(j=0;j<M.vexnum;++j)if(M.arcs[i][j].adj!=1)M.arcs[i][j].adj=0;}//for}//输出邻接表void PrintDN(ALGraph G){int i;ArcNode *p;printf("\n输出邻接表:\n");printf("顶点:\n");for(i=0;i<G.vexnum;++i)printf("%2c",G.vertices[i].data);printf("\n弧:\n");for(i=0;i<G.vexnum;++i){p=G.vertices[i].firstarc;while(p){printf("%c→%c(%d)\t",G.vertices[i].data,G.vertices[p->adjvex].data,p->info);p=p->nextarc;}printf("\n");}//for}int visited[MAX_VERTEX_NUM]; // 访问标志数组(全局量)void(*VisitFunc)(char* v); // 函数变量(全局量)// 从第v个顶点出发递归地深度优先遍历图G。
数据结构:图
数据结构:图在计算机科学领域,数据结构是我们组织和存储数据的方式,以便能够高效地进行操作和处理。
而图,作为一种重要的数据结构,在许多应用中都发挥着关键作用。
想象一下,我们生活中的各种关系,比如朋友关系、交通网络、电路连接等等,这些都可以用图来表示。
图由顶点(也称为节点)和边组成。
顶点代表着事物或者对象,而边则表示顶点之间的关系。
比如说,在一个社交网络中,每个人可以看作是一个顶点,如果两个人是朋友,那么在他们对应的顶点之间就会有一条边。
这种直观的表示方式让我们能够清晰地理解和分析复杂的关系。
图有两种主要的表示方式:邻接矩阵和邻接表。
邻接矩阵就像是一个表格,行和列都对应着顶点,如果两个顶点之间有边相连,对应的位置就标记为 1,否则为 0 。
这种表示方式简单直观,但当顶点数量很多而边的数量相对较少时,会浪费大量的存储空间。
邻接表则是为每个顶点创建一个链表,链表中存储着与该顶点相邻的顶点。
这种方式在处理稀疏图(边的数量相对较少的图)时,能够节省大量的空间,并且在查找相邻顶点时也比较高效。
图的遍历是操作图的重要方式之一。
深度优先遍历就像是在迷宫中一直往前走,直到走不通了再回溯;而广度优先遍历则像是以一个点为中心,一层一层地向外扩展。
深度优先遍历通常使用递归的方式实现。
从一个起始顶点开始,沿着一条路径尽可能地深入,直到无法继续,然后回溯,尝试其他的路径。
这种遍历方式在搜索、查找路径等问题中经常被使用。
广度优先遍历则使用队列来实现。
先将起始顶点入队,然后依次取出队列头部的顶点,并将其相邻的未访问过的顶点入队。
这种方式常用于计算最短路径、层次遍历等问题。
图的应用非常广泛。
在网络路由中,通过构建网络的图模型,可以找到最优的数据包传输路径;在任务调度中,可以根据任务之间的依赖关系,使用图来安排任务的执行顺序;在地图导航中,城市和道路可以表示为图,从而为用户规划最佳的出行路线。
再比如,在人工智能中的搜索算法中,图可以用来表示状态空间。
数据结构:第7章 图
6.2 图的存储结构
➢图的邻接矩阵存储表示
6.2 图的存储结构
➢采用数组表示法构造无向网G
• 输入顶点数、边数等基本数据 • 输入各顶点信息,构造顶点向量 G.vexs[n] • 初始化邻接矩阵 G.arcs • 输入各条边所依附的顶点及权值,写入邻接矩阵G.arcs
6.2 图的存储结构
➢采用邻接矩阵表示法,创建无向网G
图的定义和术语
• 对于有n个顶点的图,最多有多少条弧? (不考虑自身到自身的弧)
每个顶点最多向其它n-1个顶点分别发出一条弧 所以
• n个顶点的有向图最多可以有 n(n-1)条弧 • 考虑无向图的情况: • n个顶点的无向图最多可以有n(n-1)/2 条边
• 弧(边)数达到最大的图称作完全图
• 有很少(如e<nlogn)弧(边)的图称为稀疏图 • 反之称为稠密图
图的定义和术语
• 无向图G=(V,{E}) • 从顶点v到顶点v’的路径 是由v出发到达v’的顶点序列 • 若为有向图,则路径也是有向的 • 第一个顶点和最后一个顶点相同的路径叫做回路或环 • 序列中顶点不重复出现的路径称为简单路径 • 除了第一个顶点和最后一个顶点之外,其余顶点不重复
出现的回路称为简单回路或简单环
图的定义和术语
• 无向图G中,如果从顶点v到v’有路径, 则称v和v’是连通的
• 对于任意两个顶点都连通的图,叫做连通图 • 无向图中的极大连通子图叫做连通分量
v1
v2
v3
v4
v5
图的定义和术语
• 有向图中, • 对于任意两个顶点都存在双向路径的图,叫做强连通图 • 有向图中的极大强连通子图叫做强连通分量
6.2 图的存储结构
➢数组表示法
数据结构-图
出发点,访问D,标注数字序号④;
(a)无向图 G9
(b)深度优先遍历
图的遍历
3.1图的深度优先遍历
接着到G,访问G, 标注数字序号⑤;G 相邻顶点都访问过了,顺着虚线箭头方向
回退到 D,D 相邻顶点都访问过了,顺着虚线箭头方向回退到C,C 相邻顶点也都访问过
图的基本概念
1.2图的操作定义
02
PART
图的存储结构
2.1邻接矩阵
首先介绍的是数组表示法,即用两个数组分别存储顶点的信息和顶点之间的关系。
用来存放图中 n 个顶点的数组称为顶点数组。我们可将图中顶点按任意顺序保存到顶点数组中,
这样按存放次序每个顶点就对应一个位置序号(简称位序),依次为0~n-1;接着用一个 n×n 的二维
称为有向图。例如,当V={v1,v2,v3,v4,v5},VR={<v1,v2>,
<v1,v4>,<v2,v4>,<v3,v1>,<v3,v5>,<v4,v3>,<v5,v4>},则顶点集合
V、关系集合VR 构成有向图G1=(V,VR),如图(a)所示。
图的基本概念
1.1图的定义与基本术语
无向图(Undirected Graph)。如果顶点间的关系是无
序号作为表结点的值,所以一条弧对应一个表结点。右图为有向图 G1
和无向图 G2的邻接表表示法存储示意图。
图的存储结构
2.2邻接表
对于有向网和无向网,由于表结点表示边或弧,因此需要对表结点扩充一个属性域,表
结点至少包含顶点序号、权值和下一表结点指针 3 个属性,由此构成网的邻接表。
数据结构图
所以:对于点多边少的稀疏图来说,采用邻接表 结构使得算法在时间效 率上大大提高。
16
3/12
广度优先搜索(Breadth First Search,简称BFS ) BFS类似于树的层序遍历; 用一个数组用于标志已访问与否,还需要一个工作队列。
【例】一个无向图的BFS
8
6
CD
4
7
HG
BA
邻接多重表(Adjacency Multilist)
9
边表
• 在某些应用中,有时主要考察图中边的权值以及所依附的 两个顶点,即图的结构主要由边来表示,称为边表存储结 构。
• 边表结构采用顺序存储,用2个一维数组构成,一个存储 顶点信息,一个存储边的信息。边数组的每个元素由三部 分组成:
– 边的起点下标 – 边的终点下标 – 边的权值
1
A [i][
j]
0
如果 (vi , v j ) 或 vi , v j G的边 其它
无权图的邻接矩阵表示示例
V1
V2
V0
3
V3
4 12/15
带权图的邻接矩阵的定义
A [i][ j] wij
如果 (vi , vj ) 或 vi , v j G的边 其它
带图权的图邻的接邻矩接阵矩表阵示表示示例示[例例6.9]
1
第一部分 图的定义和术语
2
图的定义
“图” G可以表示为两个集合:G =(V, E)。每条 边是一个顶点对(v, w) E ,并且 v, w V。
通常:用 |V| 表示顶点的数量(|V| ≥ 1), 用 |E| 表示边的数量(|E| ≥ 0)。
(1) 无向图(完全有向图边数与顶点数之间的 关系) (2) 有向图(完全有向图弧数与顶点数之间的 关系) (3) 简单图:没有重边和自回路的图 (4) 邻接 (5) 路径,路径长度 (6) 无环(有向)图:没有任何回路的(有向)图 (7) 度,入度,出度 (8) 无向图的顶点连通、连通图、连通分量 (9) 有向图的顶点强连通,强连通图、连通分量
数据结构-图及其存储结构
for (j=0;j<G.vexnum;+ +j ) adj Info G.arcs[i][j]={∞,NULL}; //Arccell的形式为: for (k=0;k<G.arcnum;+ +i ) { //二维数组存放各边上的信息 scanf(v1,v2,w); i=locatevex(G,v1); j=locatevex(G,v2); //求顶点v1,v2在图中的位置 G.arcs[i][j].adj=w; G.arcs[j][i].adj=w; //无向网的邻接矩阵是对称的 if (IncInfo) Input (*G.arcs[i][j].info); //将弧上的信息存储在指针info
case UDN: return CreateUDN(G);
default : return ERROR; }//CreateGraph
二、存储结构
2.数组表示法前提下图的输入
*以无向网为例,即当用户输入图的类型标志为UDN时,有:
Status CreateUDN(MGraph &G){ scanf(G.vexnum,G.arcnum,IncInfo); //IncInfo 为0时表示各弧
v2 6 5
v1 5 1 5 v3 3 6 4 2 v4
一个连通无向图的生成树是该图的一个连通分量,它 包含有该图的所有n个顶点以及连接这n个顶点的(n-1) 条边。 边或弧上带权值的图称为带权图或网(分为无向网和 有向网)。 一个无向图的所有生成树中,边上的权值之和最小的 生成树称为该图的最小生成树或最小代价生成树。
《数据结构之图》相关知识点总结
第5章图●图的定义①图由顶点集V和边集E组成,记为G=(V,E),V(G)是图G中顶点的有穷非空集合,E(G)是图G中顶点之间变得关系集合,|V|表示顶点个数,也称图的阶,|E|表示边数(线性表和树都可以是空的,但图可以只有一个顶点没有边)②有向图:弧是顶点的有序对,记为<v,w>,v,w是顶点,v是弧尾,w是弧头,从顶点v到顶点w的弧。
无向图:边是顶点的无序对,记为(v,w)③简单图:一个图满足:不存在重复边;不存在顶点到自身的边。
多重图相对于简单图定义④完全图:无向图中,任意两顶点之间存在边,称为完全无向图。
N个顶点的无向完全图有n(n-1)/2条边。
在有向图中,任意两顶点之间存在方向相反的两条弧,称为有向完全图,N 个顶点的有向完全图有n(n-1)条边。
⑤连通图:在无向图中任意两顶点都是连通的。
无向图中的极大连通子图称为连通分量。
极大要求连通子图包含其所有的边和顶点,极小连通子图既要保持图连通,又要保持边数最少⑥在有向图中任意两顶点v,w,存在从顶点v到顶点w和从顶点w到顶点v两条路径,这种图称为强连通图。
有向图的极大强连通子图称为有向图的强连通分量。
⑦生成树:①包含图中所有顶点n,②生成树有n-1条边, ③任意两点连通。
对生成树而言,砍去一条边变成非连通图,加上一条边形成一个回路。
在非连通图中,连通分量的生成树构成了非连通图的生成森林。
⑧顶点的度:以该顶点为端点的边的数目。
无向图的全部顶点的度之和等于边数的两倍。
有向图的度等于出度和入度之和,入度是以该顶点为终点的有向边的数目,出度是以该顶点为起点的有向边的数目。
有向图的全部顶点的入度之和和出度之和相等且等于边数。
⑨图中每条边可以标上具有某种含义的数值,该数值称为边的权值。
带有权值的图称为网。
○10对于无向图G=(V, {E}),如果边(v,v’)∈E,则称顶点v,v’互为邻接点,即v,v’相邻接。
边(v,v’)依附于顶点v 和v’,或者说边(v, v’)与顶点v 和v’相关联。
数据结构_图_采用邻接矩阵存储,构造无向图
1.采用邻接矩阵(邻接表)存储,构造无向图(网)输入:顶点数、边数、顶点信息、边信息输出:图的顶点,图的边邻接矩阵(数组表示法)处理方法:用一个一维数组存储图中顶点的信息,用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。
假设图G=(V,E)有n个顶点,则邻接矩阵是一个n×n 的方阵,定义为:如果(vi,vj)属于边集,则edges[i][j]=1,否则edges[i][j]=0。
邻接表存储的处理方法:对于图的每个顶点vi,将所有邻接于vi的顶点链成一个单链表,称为顶点vi的边表(对于有向图则称为出边表),所有边表的头指针和存储顶点信息的一维数组构成了顶点表。
程序代码:#include<iostream>using namespace std;#define MAX_VERTEX_NUM 20 //最大顶点个数#define OK 1typedef int Status;//图的数组(邻接矩阵)存储表示typedef struct ArcCell { // 弧的定义int adj; // VRType是顶点关系类型。
// 对无权图,用1或0表示相邻否;// 对带权图,则为权值类型。
int *info; // 该弧相关信息的指针} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct { // 图的定义char vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数、弧数} MGraph;int LocateV ex(MGraph G, char v){int a;for (int i = 0; i <= G.vexnum; i++){if (G.vexs[i] == v)a= i;}return a;}Status CreateUDN(MGraph &G) { //采用邻接矩阵表示法,构造无向网Gint i, j, k, w;char v1, v2;cout <<"输入顶点数,边数:"<< endl;cin >> G.vexnum >> G.arcnum;//IncInfo为0,表示各弧无信息cout <<"各顶点分别为:"<< endl;for (i = 0; i<G.vexnum; i++)cin >> G.vexs[i]; //构造顶点向量for (i = 0; i<G.vexnum; i++) //初始化邻接矩阵for (j = 0; j<G.vexnum; j++){G.arcs[i][j].adj =NULL;}cout <<"顶点信息、边信息:"<< endl;for (k = 0; k<G.arcnum; k++) { //构造邻接矩阵cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值i = LocateV ex(G, v1); j = LocateV ex(G, v2);G.arcs[i][j].adj = w;G.arcs[j][i] = G.arcs[i][j];} return OK;} //CreateUDN (p162 算法7.2)Status printf1(MGraph G){cout <<"该图的顶点分别为:";for (int i = 0; i<G.vexnum; i++)cout << G.vexs[i] <<"";return OK;}Status printf2(MGraph G){cout <<"该图的边为:";for (int i = 1; i<G.vexnum; i++) //初始化邻接矩阵for (int j = 0; j<i; j++){if (G.arcs[i][j].adj !=NULL)cout << G.vexs[j]<< G.vexs[i] <<"," ;}return OK;}int main(){MGraph G;CreateUDN(G);printf1(G);cout << endl;printf2(G);cout << endl;system("pause");return 0;}。
图的几种存储方式
之前几天把数据结构扔在一边,在看离散数学的图论部分,看了大部分,最后还是觉得纯数学的,有一些可能现在我刚接触图还不会觉得有什么用,所以就选择性的跳过一些,现在也决定先放下书,回到数据结构上,开始图的部分的学习。
图的存储通用的存储方式有邻接矩阵表示法、邻接表表示法。
为方便有向图的顶点的入度与出度的计算,有有向图的十字链表表示法。
为方便对无向图的边进行操作,有无向图的邻接多重表表示法。
邻接矩阵表示法应该算是最容易的一种表示法,一些简单的操作比如查找某顶点的指定邻接点等很容易实现。
邻接表表示在计算无向图顶点的度很方便,计算有向图的出度也很方便,但是计算入度的话就要从第一个结点开始遍历,比较麻烦,这时采用逆邻接表表示法的话,求有向图的入度就会很方便,相应的,出度就不方便了,所以要根据需要选择存储结构。
如果在程序中要统计有向图的度,那么最好的方式就是采用十字链表的存储方式。
邻接多重表可以看作是对无向图的邻接矩阵的一种压缩表示,当然这种结构在边的操作上会方便很多,但是我现在还没学到,所以暂时还不知道。
下面是几种表示方法的算法实现,逆邻接表和邻接表的实现方式几乎一样,所以就不贴出来了。
1.#define MAX_VERTEX_NUM 202.3.#include<iostream>4.#include<string>ing namespace std;6.7.template<class T>8.int Locate_Vex(T G,string x) //定位顶点位置9.{10.for(int k=0;G.vexs[k]!=x;k++);11.return k;12.}13.14.//邻接矩阵存储图15.struct MGraph16.{17. string vexs[MAX_VERTEX_NUM];//顶点数组18.int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵19.int vexnum;//顶点数目20.int arcnum;//边数目21.};22.23.void CreateUDN_MG(MGraph &G)24.{25.//采用邻接矩阵表示法,构造无向网26. cin>>G.vexnum>>G.arcnum;27.for(int i=0;i<G.vexnum;i++)28. cin>>vaxs[i];29.30.for(i=0;i<G.vexnum;i++)31.for(int j=0;j<G.vexnum;j++)32. G.arcs[i][j]=-1;33.//上面是初始化邻接矩阵,-1表示两点间边的权值为无穷大34.35.for(int k=0;k<G.arcnum;k++)36. {37. string v1,v2;38.int w;39. cin>>v1>>v2>>w;40. i=Locate_Vex(G,v1);41. j=Locate_Vex(G,v2);42.while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)43. {44. cout<<"结点位置输入错误,重新输入: ";45. cin>>v1>>v2>>w;46. i=Locate_Vex(G,v1);47. j=Locate_Vex(G,v2);48. }49. G.arcs[i][j]=w;50. G.arcs[j][i]=G.arcs[i][j]; //置对称边51. }52.}53.54.//邻接表存储图55.//表结点56.struct ArcNode57.{58.int adjvex; //弧所指向顶点的位置59. ArcNode *nextarc;// 指向下一条弧60.};61.62.//头结点63.typedef struct VNode64.{65. string data;//顶点名66. ArcNode *firstarc;//指向第一条关联顶点的弧67.}AdjList[MAX_VERTEX_NUM];68.69.struct ALGraph70.{71. AdjList vertices;//头结点数组72.int vexnum;73.int arcnum;74.};75.76.void CreateDG_ALG(ALGraph &G)77.{78.//采用邻接表存储表示,构造有向图G79. string v1,v2;80.int i,j,k;81. cin>>G.arcnum>>G.vexnum;82.83.//构造头结点数组84.for(i=0;i<G.vexnum;i++)85. {86. cin>>G.vertices[i].data;87. G.vertices[i].firstarc=NULL;88. }89.90.//输入各弧并构造邻接表91.for(k=0;k<G.arcnum;k++)92. {93. cin>>v1>>v2;94. i=Locate_Vex(G,v1);95. j=Locate_Vex(G,v2);96.while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)97. {98. cout<<"结点位置输入错误,重新输入: ";99. cin>>v1>>v2;100. i=Locate_Vex(G,v1);101. j=Locate_Vex(G,v2);102. }103.104. ArcNode *p=new ArcNode;105. p->adjvex=j;106. p->nextarc=NULL;107. p->nextarc=G.vertices[i].firstarc;108. G.vertices[i].firstarc=p;109. }110.}111.112.//十字链表方式存储有向图113.//弧结点114.struct ArcBox115.{116.int tailvex,headvex;//弧结点头尾结点位置117. ArcBox *hlink,*tlink;//弧头和弧尾相同的弧的链域118.};119.120.//顶点结点121.struct VexNode122.{123. string data;124. ArcBox *firstin,*firstout;//顶点第一条入弧和出弧125.};126.127.struct OLGraph128.{129. VexNode xlist[MAX_VERTEX_NUM];130.int vexnum;131.int arcnum;132.};133.134.void CreateDG_OLG(OLGraph &G)135.{136.//采用十字链表存储表示,构造有向图G137. string v1,v2;138.int i,j,k;139. cin>>G.vexnum>>G.arcnum;140.for(i=0;i<G.vexnum;i++)141. {142. cin>>G.xlist[i].data;143. G.xlist[i].firstin=NULL;144. G.xlist[i].firstout=NULL;145. }146.for(k=0;k<G.arcnum;k++)147. {148. cin>>v1>>v2;149. i=Locate_Vex(G,v1);150. j=Locate_Vex(G,v2);151.152.while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1) 153. {154. cout<<"结点位置输入错误,重新输入: ";155. cin>>v1>>v2;156. i=Locate_Vex(G,v1);157. j=Locate_Vex(G,v2);158. }159.160. ArcBox *p=new ArcBox;161. p->tailvex=i;162. p->headvex=j;163. p->hlink=G.xlist[j].firstin;164. p->tlink=G.xlist[i].firstout;165. G.xlist[i].firstout=G.xlist[j].firstin=p;166. }167.}168.169.//邻接多重表存储170.//边结点171.struct EBox172.{173.int mark;//标志域,指示该边是否被访问过(0:没有 1:有) 174.int ivex,jvex;//该边关联的两个顶点的位置175. EBox *ilink,*jlink;//分别指向关联这两个顶点的下一条边176.};177.178.//顶点结点179.struct VexBox180.{181. string data;182. EBox *firstedge;//指向第一条关联该结点的边183.};184.185.struct AMLGraph186.{187. VexBox adjmulist[MAX_VERTEX_NUM];188.int vexnum;189.int arcnum;190.};191.192.void CreateUDG_AML(AMLGraph &G)193.{194.//用邻接多重表存储,构造无向图G195. string v1,v2;196.int i,j,k;197. cin>>G.vexnum>>G.arcnum;198.for(i=0;i<G.vexnum;i++)199. {200. cin>>G.adjmulist[i].data;201. G.adjmulist[i].firstedge=NULL;202. }203.204.for(k=0;k<G.arcnum;k++)205. {206. cin>>v1>>v2;207. i=Locate_Vex(G,v1);208. j=Locate_Vex(G,v2);209.210.while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1) 211. {212. cout<<"结点位置输入错误,重新输入: ";213. cin>>v1>>v2;214. i=Locate_Vex(G,v1);215. j=Locate_Vex(G,v2);216. }217.218. EBox *p=new EBox;219. p->ivex=i;220. p->jvex=j;221. p->ilink=G.adjmulist[i].firstedge;222. p->jlink=G.adjmulist[j].firstedge;223. p->mark=0;224. G.adjmulist[i].firstedge=G.adjmulist[j].firstedge=p; 225. }226.}。
数据结构-图的定义和术语
继续进行 ·3
·4
搜索。
·5
·6
·7
·3 ·1
·2
·4 从结点 5 出发的搜索序列:
5、6、2、3、1、4、7 适用的数据结构:栈
图的遍历
2、广度(宽度)优先搜索:
• 树:
A
B
C
D
EFG H
I JK
树的按层次进行访问的次序: A、B、C、D、E、F、G、H、 I、J、K、L
适用的数据结构:队列
L A
1
·1
2
12
11
·2
·11
·12
3
6
7
10
·3 ·6 ·7
·10
4
5
8
9
·4 ·5 ·8
·9
图的广度优先的访问次序:
1、2、11、12、3、6、7、10、4、5、8、9
适用的数据结构:队列
图的连通性问题
2、有向图的强连通分量的求法:续 •强连通分量的求法:
1、对有向图 G 进行深度为主的搜索,按照退 出该结点的次序给结点进行编号。最先退 出的结点的编号为 1,其它结点的编号按 次序逐次增大 1。
点1
3 已在U中
16 21 35
0 0 0
lowcost 表示最小距离
4∞ 0
adjvex 表示相应结点(在V -U中的)
5∞
0
lowcost adjvex
U1
6
5 1
25 35 4
3
6
4
2
566 图G
数组:closedge[ 6 ]
00 15 2 20 35 0 46 2 54 2
lowcost adjvex
数据结构(C++)--图
一、图的概念 二、图的应用 三、图的基本术语 四、图的存储结构
难点
1
一、图的概念
(Graph) Graph)
定义:图是由顶点集合(vertex)及边的集合 定义:图是由顶点集合 及边的集合 组成的一种数据结构: 组成的一种数据结构: Graph= Graph=( V, R ) 其中: 某个数据对象} 其中: V = { x | x ∈ 某个数据对象} 是顶点的有穷非空集合; 是顶点的有穷非空集合; R = {(u, v) | u, v ∈ V } {(u 是顶点之间关系的有穷集合, 是顶点之间关系的有穷集合,也叫做 (edge)集合 集合。 边(edge)集合。
1, 如果 < i , j >∈ E 或者 (i , j ) ∈ E Matrix[i ][ j ] = 0, 否则
1 7 3 4 2 8 3 1 6 5 5 4 2
最小(生成 树 最小 生成)树 生成 也称为 最小(支撑 树 最小 支撑)树 支撑
5
二、图的应用举例
例2: 最短路问题(SPP-Shortest Path Problem) : 最短路问题( ) 一名货柜车司机奉命在最短的时间内将一车货物从 甲地运往乙地。从甲地到乙地的公路网纵横交错, 甲地运往乙地。从甲地到乙地的公路网纵横交错, 因此有多种行车路线,这名司机应选择哪条线路呢? 因此有多种行车路线,这名司机应选择哪条线路呢? 假设货柜车的运行速度是恒定的, 假设货柜车的运行速度是恒定的,那么这一问题相 当于需要找到一条从甲地到乙地的最短路。 当于需要找到一条从甲地到乙地的最短路。 5 A 7 C 4 B 6 4 F 5 3 E 1
5 (开始) A 开始) 7 4
第1.5章 数据结构——非线性结构(图形结构)
邻接矩阵表示法
根据图的定义可知,一个图的逻辑结构分两部分,一 根据图的定义可知,一个图的逻辑结构分两部分, 部分是组成图的顶点的集合;另一部分是顶点之间的联系, 部分是组成图的顶点的集合;另一部分是顶点之间的联系, 即边或弧的集合。因此, 即边或弧的集合。因此,在计算机中存储图只要解决对这 两部分的存储表示即可。 两部分的存储表示即可。 可用一个一维数组存放图中所有顶点的信息; 可用一个一维数组存放图中所有顶点的信息;用一个 二维数组来存放数据元素之间的关系的信息(即边或弧的 二维数组来存放数据元素之间的关系的信息 即边或弧的 集合E)。这个二维数组称之为邻接矩阵 邻接矩阵。 集合 。这个二维数组称之为邻接矩阵。
The College of Computer Science and Technology
1
1 2 3 3
1 2 3 4
2 1 1 1 (b)
3 3 2 2
4 4 4 3
2
4 (a)
4
The College of Computer Science and Technology
5.3 图的遍历
和树的遍历类似, 和树的遍历类似,从图中某一顶点出发访问图中其余 的顶点,使每个顶点都被访问且仅被访问一次, 的顶点,使每个顶点都被访问且仅被访问一次,这个过程 就叫做图的遍历(traversing graph)。图的遍历算法 就叫做图的遍历 。 是求解图的连通性问题、 是求解图的连通性问题、拓扑排序和求关键路径等算法的 基础。 基础。 然而,图的遍历要比树的遍历复杂得多, 然而,图的遍历要比树的遍历复杂得多,因为图中任 一顶点都可能和其余的顶点相邻接, 一顶点都可能和其余的顶点相邻接,所以在访问了某个顶 点之后,可能沿着某条路径搜索之后,又回到该顶点上。 点之后,可能沿着某条路径搜索之后,又回到该顶点上。 为避免同一顶点被访问多次,在遍历图的过程中, 为避免同一顶点被访问多次,在遍历图的过程中,必须记 下每个已访问过的顶点。为此,设一个辅助数组 下每个已访问过的顶点。为此,设一个辅助数组 visited[n],它的初值为“ 或者零, visited[n],它的初值为“假”或者零,一旦访问了顶点 Vi,便置 便置visited[i]为“真”或者为被访问时的次序号。 或者为被访问时的次序号。 为
图的存储实验报告
图的存储实验报告图的存储实验报告引言在计算机科学领域中,图是一种重要的数据结构,用于描述对象之间的关系。
图的存储方式对于图的遍历、搜索和其他操作有着重要的影响。
本实验旨在探究不同的图存储方式,并比较它们在不同操作下的性能差异。
一、邻接矩阵存储方式邻接矩阵是一种常见的图存储方式,它使用二维数组来表示图中各个顶点之间的关系。
在邻接矩阵中,行和列分别代表图中的顶点,矩阵中的元素表示两个顶点之间的边的关系。
实验中,我们通过一个简单的例子来说明邻接矩阵的存储方式。
假设有一个无向图,其中包含5个顶点和6条边。
我们可以使用一个5x5的矩阵来表示这个图,矩阵中的元素为1表示两个顶点之间存在边,为0表示不存在边。
邻接矩阵的优点是可以快速判断两个顶点之间是否存在边,时间复杂度为O(1)。
然而,邻接矩阵的缺点是当图中的边数较少时,会造成存储空间的浪费。
此外,在图中顶点的增加和删除操作时,需要重新调整矩阵的大小,开销较大。
二、邻接表存储方式邻接表是另一种常见的图存储方式,它使用链表来表示图中各个顶点之间的关系。
在邻接表中,每个顶点都有一个链表,链表中存储了与该顶点相邻的顶点。
实验中,我们同样以一个简单的例子来说明邻接表的存储方式。
假设有一个有向图,其中包含4个顶点和5条边。
我们可以使用一个包含4个链表的数组来表示这个图,数组中的每个元素表示一个顶点,链表中的元素表示与该顶点相邻的顶点。
邻接表的优点是在图中边的数量较少时,可以节省存储空间。
此外,在图中顶点的增加和删除操作时,开销较小。
然而,邻接表的缺点是判断两个顶点之间是否存在边的时间复杂度较高,需要遍历链表,时间复杂度为O(顶点的度数)。
三、性能比较与结论通过实验,我们对比了邻接矩阵和邻接表两种图存储方式在不同操作下的性能差异。
在判断两个顶点之间是否存在边的操作中,邻接矩阵的时间复杂度为O(1),而邻接表的时间复杂度为O(顶点的度数)。
因此,在此操作下,邻接矩阵的性能更优。
图形结构与知识点总结
图形结构与知识点总结一、引言图形结构是计算机科学中一种重要的数据结构,它是一种通过连接各种数据项来表示抽象实体之间关系的数据结构。
图形结构广泛应用于计算机网络、社交网络、路由算法、图像处理、计算机图形学、人工智能等领域。
在本次总结中,我们将深入探讨图形结构的基本概念、存储表示、图的遍历、最短路径算法、最小生成树算法等知识点,并对相关知识进行系统总结。
二、基本概念1.图形结构的定义图形是一个由结点和边组成的数学模型,它表示了一些对象之间的二元关系。
其中,结点表示对象,边表示对象之间的关系。
图形结构可以分为有向图和无向图。
2.图的术语图的术语包括结点、边、度、路径、环、连通图等。
结点是图形中的基本单位,边表示结点之间的关系,度是结点所连接的边的数量,路径是从一个结点到另一个结点的边的序列,环是起点和终点相同的路径,连通图是图中任意两个结点之间都存在路径的图。
三、存储表示1.邻接矩阵邻接矩阵是一种常用的图形结构存储表示方法。
它使用一个二维数组来表示结点之间的边的关系,其中数组的值表示边的权重或是否存在边。
邻接矩阵适合表示稠密图,但对于稀疏图来说,它会浪费大量的空间。
2.邻接表邻接表是另一种常用的图形结构存储表示方法。
它使用一个数组和一个链表来表示结点之间的边的关系,数组中的元素表示结点,链表中的元素表示结点的邻接结点。
邻接表适合表示稀疏图,但对于稠密图来说,查找邻接结点会消耗较多的时间。
3.其他存储表示方法除了邻接矩阵和邻接表之外,还有其他存储表示方法,如邻接多重表、十字链表等。
这些方法适用于特定类型的图,可以根据具体情况选择合适的存储表示方法。
四、图的遍历1.深度优先搜索(DFS)深度优先搜索是一种图的遍历算法,它从起始结点开始,沿着一条路径一直向下搜索,直到遇到已访问过的结点或者死路为止,然后回溯到最近的一个分支结点继续搜索。
DFS可以用递归或者栈来实现。
2.广度优先搜索(BFS)广度优先搜索是另一种图的遍历算法,它从起始结点开始,一层一层地往外扩展,直到遍历完所有结点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
@staticmethod def _out_edges(mat, v): edges = [] row = mat[v] for i in range(len(row)): if row[i] != 0 and row[i] != inf: edges.append((i, row[i])) # (邻接点,边权) return edges
2016 《数据结构》
图
主要内容
图的概念和操作 图的存储:邻接矩阵,邻接表 图的遍历:宽度优先,深度优先 生成树:DFS 生成树,BFS 生成树 最小生成树:Prim 算法,Kruskal 算法 最短路径问题:
单源点最短路径和 Dijkstra 算法 所有顶点之间的最短路径和 Floyd 算法
2018/3/7
第七章 图
21
获取顶点v的所有“邻接点”(邻接边、出边)
def out_edges(self, v): '''获取v的所有(邻接点,边权)对,以list形式返回''' assert 0 <= v < self._vnum return self._mat[v]
2018/3/7
第七章 图
2018/3/7
第七章 图
24
2018/3/7
第七章 图
25
无权图的读入
input = sys.stdin.read()
data = list(map(int, input.split())) n, m = data[0:2] data = data[2:] edges = list(zip(data[0:(2 * m):2], data[1:(2 * m):2])) adj = [[] for _ in range(n)] for (a, b) in edges: adj[a - 1].append(b - 1) adj[b - 1].append(a - 1) # 有向图去除此句!
8
A
3 9 4
6 5 1
D
2
0 3 5 0 1 9 0 6
8 4 2 0
14
B
2018/3/7
C
g3.out_edges(2) = [ (0, 9), (3, 2) ]
获取顶点v的所有“邻接点”(邻接边、出边)
def out_edges(self, v): '''获取v的所有(邻接点,边权)对,以list形式返回''' assert 0 <= v < self._vnum # 用assert替代异常 return Graph._out_edges(self._mat, v)
2018/3/7 第七章 图 27
将标准输入stdin重定向到文件
import sys # 导入sys模块 input = sys.stdin.read() 这里要在 console窗口 中,转到文件所在的目录,执行命令: python **.py < graph.txt 其中: **.py 是包含代码段的文件 graph.txt是图信息文件,和**.py在同一目录下
g1.out_edges(1) = [ (0, 1), (4, 1), (5, 1) ]
第七章 图
17
有向图的邻接表
A
B C E
0 1 2 3 4 A B 1 2 3 0 2 ^ ^ ^ 1 ^ 4 ^
C
D E
D
Python中list的list:
[ [(1, 1), (4, 1)], [(2, 1)], [(3, 1)], [(0, 1), (1, 1)] [(2, 1)] ]
22
说明
课本中对无权、有权图统一处理了,具体应用中 可针对图的类型做专门的定义,使得无权图的邻 接点集是单纯的点集,不是(u, 1)形式的边对。
通常对图的表示和操作,直接使用list的list型的对 象即可,不需要封装成专门Graph类型。
2018/3/7
第七章 图
23
由文件中读入图信息
UCSD_Algorithms on Graph
0
A
1 2 0 0
3 1 9 6 ^
2 0 3
5 4 ^ 2 ^
3
8 ^
1
2 3
B
C D
B
1
C
Python中list的list:
[ [(1, 3), (2, 5), (3, 8)], [(2, 1), (0, 4)], [(0, 9), (3, 2)], [(0, 6)] ]
2018/3/7
g3.out_edges(2) = [ (0, 9), (3, 2) ]
2018/3/7
第七章 图
15
邻接表 Adjacent List
(邻接矩阵的压缩)
2018/3/7
第七章 图
16
无向图的邻接表
B A
F E
C
D
0
1 2 3 4 5
A B C D E F
1
0 3 2 0 1
4
4 5 5 1 2
^
5 ^ ^ ^ 3 ^ ^
Python中list的list: [ [(1, 1), (4, 1)], [(0, 1), (4, 1)], [(3, 1), (5, 1)], [(2, 1), (5, 1)], [(0, 1), (1, 1)], [(1, 1), (2, 1), (3, 1)] ] 2018/3/7
B A F
C
D
E
Python等长list的list:
[ [0, 1, 0, 0, 1, 0], [1, 0, 0, 0, 1, 1], [0, 0, 0, 1, 0, 1], [1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 0, 0] ]
2018/3/7 第七章 图 10
有向图的邻接矩阵:非对称
第七章 图
20
图的建立——邻接表
# 课本采用了继承方式,逻辑上不是太好!
class GraphA(Graph): def __init__(self, mat): vnum = len(mat)
# mat是等长list的list
# 所有顶点的(邻接点,边权)对的list self._mat = [Graph._out_edges(mat, i) for i in range(vnum)] self._vnum = vnum
12
2018/3/7
第七章 图
图的建立——邻接矩阵
class Graph: def __init__(self, mat): vnum = len(mat) # 对传入的mat做了拷贝构造 self._mat = [mat[i][:] for i in range(vnum)] self._vnum = vnum
2018/3/7
第七章 图
13
获取顶点v的所有“邻接点”
B A F E C
0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0
D
g1.out_edges(1) = [ (0, 1), (4, 1), (5, 1) ]
关系集
顶点之间关系,即边集或弧集 边或弧的总数
图的类型
有向、无向、带权、不带权
第七章 图 *
*
邻接矩阵 Adjacent Matrix
2018/3/7
第七章 图
9
无向图的邻接Байду номын сангаас阵:对称
0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 0 0
也可以: python **.py 然后手工输入图信息,以Ctrl+Z结束输入。
2018/3/7
第七章 图
28
AOV 网,拓扑排序
AOE 网,关键路径
*
第七章 图
*
无向图、有向图、带权图(网)
B A F E A
3 9 4 5 8 6
C D B C D
2
A E D
B
2018/3/7
1
第七章 图
C
3
图的概念
Graph=( V, E )
V = { v | v 某数据对象}
• 顶点的有穷非空集合;
v
*
第七章 图
图的基本操作
ADT Graph:
Graph(self)
vertex_num(self) vertices(self) add_vertex(self, v) add_edge(self, v1, v2) get_edge(self, v1, v2) out_edges(self, v) degree(self, v)
E = {(u, v) | u, v V } 或 E = {<u, v> | x, y V}
• 是顶点之间关系的有穷集合,也叫边(或弧)集合。
u
v
u
v
• 称u、v互为邻接点。
2018/3/7
第七章 图
4
顶点的度
与之相关联的边或弧的数目 有向图:D(v)=ID(v)+OD(v)
ID(v): 入度(in-degree),即入边数; OD(v):出度(out-degree),即出边数。
*
第七章 图
*