图的存储

184 阅读2分钟

图的定义

图是由点和连接点的边组成的,树是一种特殊的图,是一种连通无环图。

图的分类

我们可以根据边有无方向、有无权值、有无环路进行分类:

  1. 无向无权图,边没有权值、没有方向
  2. 有向无权图,边没有权值、有方向
  3. 加权无向图
  4. 加权有向图
  5. 有向无环图

图的存储

有3种数据结构可以存储图,如邻接矩阵、邻接表、链式前向星

1.邻接矩阵

用二维数组定义:int g[ N ][ N ];
无向图:g[i][j]=g[j][i];
有向图:g[i][j]!=g[j][i];
权值:g[i][j]存结点i到节点j的权值。

优点:适合稠密图,对边的增删改查操作简单。
缺点:
1. 存储复杂度高,可能会造成空间浪费
2. 一般情况下不能存重边

2.邻接表

struct edge//边 
{
	int from,to,w;//边:起点from、终点to、权值w 
	edge(int a,int b,int c)
	{
		from=a;
		to=b;
		w=c;
	}
	
} 
vector<edge> e[N];//e[i]:存第i个结点连接的所有边** 

优点:适用于稀疏图,存储效率比较高,存储时间复杂度O(V+E).可以存重边。
缺点:编程比邻接矩阵麻烦、访问和修改慢。

3.链式前向星

//链式前向星
struct Edge
{
	int to,next,w;//边:到to、下一个边next、权值w。起点存在head中
	Edge(int a,int b,int c){to=a;next=b;w=c;} 
} edge[N];
int head[N];//h[i]表示 结点i指向的第一条边的位置
int idx;//记录head的末尾位置 
void init()//初始化 
{
	for(int i=0;i<N;i++)
	{
		head[i]=-1;//表示没有节点从i出发 
	}
}
void addEdge(int from,int to,int w)//添加节点和边 
{
	edge[idx].to=to;
	edge[idx].w=w;
	edge[idx].next=head[from];//将当前边插入到 节点from指向的集合中 。 
	head[from]=idx++;//修改from指向的位置。 
}

优点:存储效率高
缺点:不方便做删除操作。