图的总结
一、思维导图 :
二、基本概念:
(一)术语概念:
1:端点和领接点:一条边的两端点互相称为领接点,有向图中又分为出边和入边领接点
2:顶点的度,入度和出度:一个顶点所关联的边的数目称为顶点的度,有向图中又分为入度和出度。
3:完全图:有向图中每两个顶点之间都有两条方向相反的边
4:稠密图,稀疏图:图接近完全图时,称为稠密图,边数少叫做稀疏图
5:子图:类似于数学中的子集, G=(V,E) , G'=(V',E'), V',E'是V,E,的子集,说G‘是G的子图
6:路径和路径长度:两个点之间的路径是顶点序列。路径长度是一条路径上经过边的数目
7:回路和环:开始点和结束点相同
8:连通图和连通分量:顶点i可以到达顶点j,则称俩顶点连通,如果图中任意两顶点都是连通的,则称图为连通图。无向图G中的极大连通子图称为G的连通分量
9:强连通图和强连通分量:从顶点i到顶点j都有路径,则称图为强连通图。强连通分量同上
10:权和网:与边相关的数值。
(二)存储结构和基本算法:
1:领接矩阵:类似与线性代数中的矩阵
特点:1)领接矩阵的表示方法唯一
2)n个顶点的图,领接矩阵储存空间为(n^2)
3)无向图的领接矩阵是对称的
4)有向图的第i行(列)非0(无穷)元素个数为该顶点的出度(入度)。无向图则为该顶点的度。
2:邻接表:顺序和链式相结合的存储方法
特点:1)邻接表的表示不唯一,因为在每个顶点对应的单链表中各边结点的链接次序可以是任意的,取决于建立邻接表的算法以及边的输人次序
2)对于有n个顶点和e条边的无向图,其邻接表有n个头结点和2e个边结点;对于有n个顶点和e条边的有向图,其邻接表有n个头结点和e个边结点。
3)对于无向图,邻接表中顶点i对应的第i个单链表的边结点数目正好是顶点i <的度。
4) 对于有向图,邻接表中顶点i对应的第i个单链表的边结点数目仅仅是顶点i的出度。顶点i的人度为邻接表中所有adjvex域值为i的边结点数目
5)在邻接表中,查找顶点i关联的所有边是非常快速的,所以在需要提取某个顶点的所有邻接点的算法中通常采用邻接表存储结构
3:十字链表法,领接多重表
(三)图的遍历
1)广度优先:首先访问初始点V,接着访问顶点V的所有未被访问过的邻接点V1,U2,".,V,然后再按照V,7V....,U,的次序访问每一个顶点的所有未被访问过的邻接点,依此类推
2)深度优先:图的深度优先遍历过程是从初始点0出发,以纵向的方式-步步向前访向各个顶点的,且找不到相邻的顶点就回退。
(四)生成树和最小生成树
最小生成树原则:
1)必须只使用该图中的边来构造最小生成树
2)必须使用且仅使用(n-1)条边来连接图中的n个顶点;
3)不能使用产生回路的边
Prim算法,克鲁斯卡尔算法
(五)最短路径
在一个不带权图中,若从一顶点到另一顶点存在着一 条路径 ,则称该路径长度为该路径上所经过的边的数目,它等于该路径上的顶点数减1。由于从一顶点到另一顶点可能存在
着多条路径,每条路径上所经过的边数可能不同,即路径长度不同,把路径长度最短(即经过的边数最少)的那条路径称为最短路径其长度称为最短路径长度或最短距离。
(五)拓扑排序
1)从有向图中选择- 一个没有前驱(即人度为0)的顶点并且输出它。
2)从图中删去该顶点,并且删去从该顶点发出的全部有向边。
3)重复1,2步骤
(六)AOE网与关键路径
1)关键路径:在AOE网中,从源点到汇点的所有路径中具有最大路径长度的路径称为关键路径
三、疑难问题
#define INF 32767 #define MAXV 1001 #include <iostream> using namespace std; typedef struct { int edges[MAXV][MAXV]; int n, e; }MGraph; void CreateMGraph(MGraph& g, int n, int e); int GetPrimSum(MGraph g, int v); int main() { MGraph g; int n, e; cin >> n >> e; CreateMGraph(g, n, e); cout << GetPrimSum(g, 1); } void CreateMGraph(MGraph& g, int n, int e) { int i, j, a, b; int length; for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { if(i==j)g.edges[i][j]=0; else g.edges[i][j]=INF; } } for (i = 0; i < e; i++) { cin >> a >> b >> length; g.edges[a][b] = length; g.edges[b][a] = length; } g.n = n; g.e = e; } int GetPrimSum(MGraph g, int v) { int Sum = 0; int i, j, k; int min; int lowcost [MAXV]; for (i = 1; i <= g.n; i++) lowcost[i] = g.edges[v][i]; for (i = 1; i < g.n; i++) { min = INF;//初始化最小值 k=0; for (j = 1; j <= g.n; j++) { if (lowcost[j] && lowcost[j] < min) { min = lowcost[j]; k = j; } } if(k==0)return -1; lowcost[k] = 0; Sum += min; for (j = 1; j <= g.n; j++) { if (lowcost[j] && g.edges[k][j] < lowcost[j]) { lowcost[j] = g.edges[k][j]; } } } return Sum; }
刚开始并没有理解题目的意思,,没有理解到题目在考关键路径的问题,认为是最短路径,通过网络查找代码理解到并纠正,写代码的过程中一开始不能很好控制GetPrimSum(MGraph g, int v)中的双重循环,也是参照网络代码又理了一边思路才完成。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步