图存储结构:
- 邻接矩阵
- 链式前向星
- C++中基于Vector的邻接表
(一)邻接矩阵
邻接矩阵是表示顶点之间相邻关系的矩阵。
基本思想为:
S[i][j]就可以表示顶点i到顶点j有条内部数值可以是边权或者bool标记有无边。
邻接矩阵的使用特点:
- 方便检查任意一对顶点间是否有边
- 方便找任一顶点的所有邻接点(邻接边)
- 方便计算任一顶点的度(直接按行或按列遍历)
对于无向图,邻接矩阵的第i行(或第i列)非零元素的个数就是该顶点的度度。
对于有向图,邻接矩阵的第i行(或第i列)非零元素的个数就是该顶点的度出度(或入度)。
最大的问题是时空耗费大。
//n个顶点,邻接矩阵a[][]
for(int i=1;i<=n;i++){
if(a[i][j]!=0){
du[i]++;
}
}
(二)链式前向星
链表可以节省空间,按边存储。
1.结构安排
//边的信息结构体,不需要存起始顶点,因为会有单独一个head[i]数组表示顶点i为起点的一条边的编号。
struct edge{
int to;//存储有向边的尾顶点,也就是指向的顶点
int next;//与此边相同起始点的下一条边
int w;//边的权值或其它含义,非必须。
};
2.增边
int head[MAXN];//记录某一个点出发的最后一条边的编号
int cnt=0;//全局,记录边的序号和总数
edge e[MAXM[;//存边数组
void add_edge(int _from,int _to,int w){
e[++cnt].to=_to;//先增加一条边,cnt先自增
e[cnt].next=head[from];
e[cnt].w=w;
head[from]=cnt;
}
3.锚定
head[i]:记录了顶点i出发的最后一条边,也是遍历的起点
for(int i=1;i<=n;i++){//遍历所有起始顶点
int p=head[i];
while(p!=0){
cout<<"从"<<i<<"到"<<e[p].to<<的边的权值为:e[p].w;
p=e[p].next;
}
}
(三)vector
vector就是(一)和(二)的结合。
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<=n;i++)
{
for (int j=0;j<vec[i].size();++j){
e=vec[i][j]; //借助中间量抽出我们的目的
cout<<"从 "<<i<<" 到 "<<e.to<<" 的值为 "<<e.w<<endl;
}
}