图的几种存储结构:
1、邻接矩阵
2、链式前向星
3、C++中vector的邻接表
(一)邻接矩阵
邻接矩阵是表示顶点之间相邻关系的矩阵。
基本思想为:
上部为无向,下部为有向
建图什么的不就有手!!就行!!
使用实际或优劣对比:
1、方便检查任意一对定点间是否存在边
2、方便找任一顶点的所有“邻接点”(有边直接相连的顶点)
3、方便计算任一顶点的度(你遍历就完了)
对于无向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的度。
对于有向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的出度(或入度)。
for(int i=1;i<=?;i++)if(a[i][j]!=0)du[i]++;
那么劣势是啥子嘞???时空关系恐惧症!!!!
(二)链式前向星
链表的话就是可以放很多东西嘛,理解的话稍微难度大一点
1、结构安排
struct edge{
int to;// 边是有向的,指向一个点
int next; // 锚定一个结点上的所有边,这个最难理解
int w; //边权,可有可无
};
2、增边
int head[MAXN]; //记录这个点上现有最后一条边的num
int cnt;//全局,记录边的序号和个数,对于边的锚定也很重要
void add(int from ,int to ,int w)
{
e[++cnt].next=head[from];
e[cnt].to=to;
e[cnt].w =w;
head[from]=cnt;
}
此处我们cnt=0,必须先自增;
3、锚定(这个蛮难的,姬某断断续续搞的差不多,真的绝绝子)
head[cnt]
记录了当前的节点的最后一条边,也是遍历的起点
每个节点第一边next=0;第二边指向第一边————最后head[点序号]指向第N边,N找到N-1(如此往复)最终到1;
(三)vector
vector就是(一)和(二)的结合,会有压边那种struct进去的直接二维vector
简单来一下二维vector就是动态了一下子,思想没变的,把from抽离出来就好了;
1、建立
struct edge{
int to;// 边是有向的,指向一个点
int w; //边权,可有可无
}e;
vector<edge>vec[MAXN];
void add(int from ,int to ,int w)
{
e.to=to;e.w=w; //借助中间变量暂时存一下
vec[from].push_back(e); //从from出发的边压了一条进去;
}
2、遍历
for(int i=1;i<=节点数;++i)
{
for (int j=0;j<vec[i].size();++j){
e=vec[i][j]; //借助中间量抽出我们的目的
cout<<"从 "<<i<<" 到 "<<e.to<<" 的值为 "<<e.value<<endl;
}
}