数据结构-图

news/2024/11/29 13:40:30/

数据结构-图

  • 1 知识框架
  • 2 图结构的存储
    • 2.1 邻接矩阵法
    • 2.2 邻接表法
    • 2.3 十字链表法
    • 2.4 邻接多重表
  • 3 图的遍历
    • 3.1 dfs(深度优先遍历)
    • 3.2 bfs(广度优先遍历)
  • 4 最小生成树
    • 4.1 Prim
    • 4.2 kruskal
  • 5 最短路径
    • 5.1 Dijkstra
    • 5.2 Floyd
  • 6 AOV网和AOE网
    • 6.1 AOV
    • 6.2 AOE

1 知识框架

在这里插入图片描述
完全图:
1.无向完全图:任意两个顶点之间存在边
在这里插入图片描述
2.有向完全图:任意两个顶点之间都存在方向相反的两条弧,则为有向完全图。
又称这一对顶点是强连通的,图中任意一对顶点都是强连通的则称此图为强连通图,其中极大强连通子图称为强连通分量。
在这里插入图片描述

2 图结构的存储

2.1 邻接矩阵法

用二维数组表示,适合稠密图

Map[Size][Size];
//顶点之间有边Map[i][j] = 1 或者等于权值 i,j之间无边等于∞

在这里插入图片描述

2.2 邻接表法

由顶点表和边表构成,顶点表数组代表所有的顶点,边表表示依附此顶点的边。

struct VerNode
{char  ver;ArcNode *first;
};//顶点表struct ArcNode
{int adjvex;ArcNode *next;
};//边表

具体图的存储实现移步例外一篇
在这里插入图片描述
在这里插入图片描述

2.3 十字链表法

只能存储有向图且空间开销太大
定义:
在这里插入图片描述
如何画出图的十字链表:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 邻接多重表

无向图的另外一种存储方式

顶点表结构:
在这里插入图片描述
边结点结构如下所示:
在这里插入图片描述
iVex和jVex表示该边的两个顶点在顶点数组adjmultiList[num]中的位置;iLink和jLink分别表示指向依附于顶点iVex和jVex下一条边的指针

如何画出邻接多重表:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3 图的遍历

3.1 dfs(深度优先遍历)

类似于树的前序遍历,利用递归的思想遍历图的所有节点

 void ALGraph::DFS(int v){int j;ArcNode *p;cout<<adjlist[v].ver<<" ";visited[v] = 1;p = adjlist[v].first;while(p){j = p->adjvex;if(visited[j] == 0)DFS(j);p = p->next;}}

3.2 bfs(广度优先遍历)

类似于树的层序遍历,同样用队列对每一个即将遍历的顶点进行入队出队操作,同时将他的邻接节点入队,直到队列为空。(可以用数组模拟队列的出队,入队操作)

为了在遍历过程中区分顶点是否被访问,设置一个访问标志数组visited[i],其初值为0,如果被访问,则置为0;

void ALGraph::BFSA(int v)   // 数组模拟队列{int queue[Size];int rear,front,i,j,tem;ArcNode *p;memset(visited,0,sizeof(visited));rear = front = -1;queue[++ rear] = v;visited[v] = 1;p = adjlist[v].first;cout<<adjlist[v].ver<<" ";while(rear != front){v = queue[++ front];p = adjlist[v].first;while(p != NULL){j = p->adjvex;if(visited[j] == 0){cout<<adjlist[j].ver<<"  ";visited[j] = 1;queue[++ rear] =  j;}p = p->next;}}}
 void ALGraph::BFSB(int v)   //使用队列{queue<int> q;int j;ArcNode *p;memset(visited,0,sizeof(visited));q.push(v);visited[v] = 1;cout<<adjlist[v].ver<<" ";p = adjlist[v].first;while(!q.empty()){v = q.front(); q.pop();p = adjlist[v].first;while(p){j = p->adjvex;if(visited[j] == 0){cout<<adjlist[j].ver<<" ";q.push(j);}p = p->next;}}}void ALGraph::DFS(int v){int j;ArcNode *p;cout<<adjlist[v].ver<<" ";visited[v] = 1;p = adjlist[v].first;while(p){j = p->adjvex;if(visited[j] == 0)DFS(j);p = p->next;}}

具体完整的代码在这篇文章

4 最小生成树

4.1 Prim

核心思想:把要生成的看做一个集合,用一个数组存储集合外的点到这个集合中点的最短距离,每次从集合中选择最小的距离,并把新的点加入到集合中,直到外部没有点

int min(shortEdge a[],int n)
{int minCost = 10000;int i,j;for(i = 0;i < n;i ++){if(a[i].lowcost != 0&&a[i].lowcost < minCost){minCost = a[i].lowcost;j = i;}}return j;
}int main()
{int verNum,arcNum;int i,j,k,root;cin>>verNum>>arcNum>>root;    //root表示节点 1~verNum,输入root选取根节点init(verNum,arcNum);for(i = 0;i < verNum;i ++){sss[i].lowcost = arc[root - 1][i];sss[i].adjvex = root - 1;}                                                  //最短边集初始化sss[root - 1].lowcost = 0;for(i = 1;i < verNum;i ++){k = min(sss,verNum);                  //选取权值最小的边sss[k].lowcost = 0;         //将顶点加入V中cout<<"("<<(sss[k].adjvex + 1)<<","<<(k + 1)<<")";for(j = 1;j < verNum;j ++){     //更新候补最短边集if(arc[k][j] < sss[j].lowcost){sss[j].lowcost = arc[k][j];sss[j].adjvex = k;}}}return 0;
}

详细过程移步这篇

4.2 kruskal

kruskal最重要的就是一个最短边集,不同于prim每次找到到集合中最短边的点,Kruskal找的是最短边集中的边,把不重复的边加入树中

详细过程看这篇

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;const int Size = 100;
int parent[Size];struct Edge
{int from,to;int info;
};struct Graph
{int vertex[Size];Edge bian[Size];int verNum,arcNum;
};void Kruskal(Graph p);
int FindRoot(int parent[],int v);main()
{struct Graph p;int i,j,k;cin>>p.verNum>>p.arcNum;for(i = 0;i < p.verNum;i ++){p.vertex[i] = i;}for(i = 0;i < p.arcNum;i ++){cin>>p.bian[i].from>>p.bian[i].to>>p.bian[i].info;}Kruskal(p);return 0;}void Kruskal(Graph p)
{int num,i,j,vex1,vex2,ans;memset(parent,-1,sizeof(parent));for(i = 0;i < p.arcNum;i ++){          //根据边集的权值由小到大排序for(j = i;j < p.arcNum;j ++){if(p.bian[i].info > p.bian[j].info){Edge tem = p.bian[i];p.bian[i] = p.bian[j];p.bian[j] = tem;}}}for(num = 0,i = 0;i < p.arcNum;i ++){vex1 = FindRoot(parent,p.bian[i].from);    //找到根节点vex2 = FindRoot(parent,p.bian[i].to);if(vex1 != vex2)    //判断是否为同一连通分量{cout<<"("<<p.bian[i].from<<","<<p.bian[i].to<<")"<<"   ";parent[vex2] = vex1;     //将vex2的上一节点设置为 vex1num ++;if(num == (p.verNum - 1)) break;}}
}int FindRoot(int parent[],int v)   //寻找根节点
{int t = v;while(parent[t] != -1){t = parent[t];}return t;
}/*
6 10
1 2 6
1 3 1
1 4 5
2 3 5
3 4 5
2 5 3
5 3 6
3 6 4
6 4 2
5 6 6(1,3)(3,6)(6,4)(3,2)(2,5)
*/

5 最短路径

5.1 Dijkstra

	核心:dist[j] = Min(dist[i]);for(k = 0;k < n;k ++)if(dist[j] > (dist[j] + arc[j][k] )dist[k] = dist[j] + arc[j][k]; 

模拟:
在这里插入图片描述

请添加图片描述
请添加图片描述

5.2 Floyd

动态规划,时间复杂度O(n³)
核心代码:

for(int k = 1;k <= n;k ++)for(int i = 1;i <= n;i ++)for(int j = 1;j <= n;j ++){if(arc[i][j] > arc[i][k] + arc[k][j])arc[i][j] = arc[i][j] > arc[i][k] + arc[k][j];}

模拟:
在这里插入图片描述
请添加图片描述

请添加图片描述
请添加图片描述

6 AOV网和AOE网

6.1 AOV

定义:用DAG图(有向无环图)表示⼀个⼯程。顶点表示活动,有向边<Vi, Vj>表示活动Vi必须先于活动Vj进行。
拓扑排序:
1.选择一个入度为0的顶点输出。
2.删除该顶点和以它为起始的边。
3.重复1,2

逆拓扑排序:
1.选择一个出度为0的顶点输出。
2.删除该顶点和以它为终点的边。
3.重复1,2

6.2 AOE

定义:边上有权值的AOV网。
性质:
1.只有某顶点所代表的事发生后,从该顶点出发的各有向边代表的活动才能开始。
2.只有在进入某顶点的各有向边所代表的活动都已结束时,该顶点所代表的事才难发生。

关键路径
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/244588.html

相关文章

纺织服装出口大国PK

【纺织服装出口大国PK】 当前&#xff0c;全球经济增长乏力&#xff0c;贸易同步走弱&#xff0c;全球主要贸易国出口增速均放缓。那么&#xff0c;全球纺织服装产业的出口情况如何&#xff1f;根据中国、孟加拉国、越南、柬埔寨等纺织服装大国发布的最新数据&#xff0c;各国纺…

分享小米笔记本格式化数据恢复的4个技巧

小米笔记本格式化恢复数据怎么弄&#xff1f;小米笔记本的数据存储在硬盘中&#xff0c;当遇到硬盘格式化的情况时。它会自动清空硬盘中的文件&#xff0c;对于不慎格式化的用户&#xff0c;数据恢复显得尤为重要。接下来&#xff0c;我们将为你分享小米笔记本格式化数据恢复的…

计算机连接电视显示超范围,HDMI连接后电脑操作界面的边框超出电视屏幕,怎么解决...

很多液晶电视通过HDMI连接到电脑上之后&#xff0c;会发生windows电脑桌面超出屏幕的现象&#xff0c;即电脑桌面的一部分会跑到电视屏幕的外边往&#xff0c;导致有些内容看不到了。导致这种现象的罪魁祸首就是电视的过扫描。 液晶电视过扫描的问题&#xff0c;主要源于电视信…

飞利浦弃意已决 冠捷顺势接手

全球消费电子产业进一步向中国转移的趋势愈来愈明显。因重要事项停牌一天后&#xff0c;长城电脑(000066)昨日发布公告&#xff0c;通过旗下子公司冠捷科技收购欧洲消费电子巨头飞利浦旗下的电视机业务。这是继当年TCL收购汤姆逊后&#xff0c;中国企业在欧洲家电市场的又一次大…

2009年20家年度失意大公司

“竞争的本质不是比谁强壮、比谁敏捷&#xff0c;更不是比谁聪明&#xff0c;而是比谁少一些愚蠢&#xff0c;少犯些错误”。《第一财经周刊》评出中国内地市场2009年度表现不佳的大公司&#xff0c;它们都遭遇到了什么样的困境&#xff1f; 为大公司“挑刺” 阿迪达斯13亿…

pytorch入门

1、下载Anaconda3 首先需要去Anaconda官网下载最新版本Anaconda3(https://www.continuum.io/downloads)&#xff0c;我下载是是带有python3.6的Anaconda3-4.4.0-Linux-x86_64.sh。 2、安装Annconda3 bash Anaconda3-4.4.0-Linux-x86_64.sh 在home/ubuntu出现anaconda3文件夹…

【OpenMMLab AI实战营第二期】MMPretrain基本使用

MMPreTrain 算法库介绍 MMPretrain 是一个全新升级的预训练开源算法框架&#xff0c;旨在提供各种强大的预训练主干网络&#xff0c; 并支持了不同的预训练策略。MMPretrain 源自著名的开源项目 MMClassification 和 MMSelfSup&#xff0c;并开发了许多令人兴奋的新功能。 目前…

Tree 树形控件一级菜单没有复选框,子菜单有复选框,如何实现?

<el-dialogtitle"技术职称选择":visible.sync"isShow"width"30%"top"50px":before-close"closeInputSelectedDepDialog"><div class"tree-content"><el-treeclass"filter-tree my-left-tree&…