文章目录
图没有顺序存储结构,但可以借助 二维数组来表示元素之间的关系,即
邻接矩阵表示法
图的链式存储结构有多种,
邻接表
、十字链表、邻接多重表
邻接矩阵、邻接表是我们重点要研究的
邻接矩阵
1、邻接矩阵表示法
建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)
- 设图A=(V,E)有 n 个顶点,则
- 图的邻接矩阵是一个二维数组A.arcs[n][n],定义为:
2、无向图的邻接矩阵表示法
分析1:无向图的邻接矩阵是对称的
分析2:顶点 i 的度=第 i 行(列)中 1 的个数
特别:完全图的邻接矩阵中,对角元素为0,其余为1
3、有向图的邻接矩阵表示法
分析1:有向图的邻接矩阵可能是不对称的
分析2:
顶点的出度=第 i 行元素之和
顶点的入度=第 i 列元素之和
顶点的度=第 i 行元素之和+第 i 列元素之和
4、网(有权图)的邻接矩阵表示法
定义为:
5、邻接矩阵的存储表示
邻接矩阵的存储表示:用两个数组
分别存储顶点表和邻接矩阵
6、采用邻接矩阵表示法创建无向网
【算法思想】
①输入总顶点数和总边数
②依次输入点的信息存入顶点表中
③初始化邻接矩阵,使每个权值初始化为极大值
④构造邻接矩阵
【算法描述】
Status CreateUDN(AMGraph &G)
{//采用邻接矩阵表示法,创建无向网G
cin>>G.vexnum>>G.arcnum; //输入总顶点数,总边数
for(i=0;i<G.vexnum;++i)
cin>>G.vexs[i]; //依次输入点的信息
for(i=0;i<G.vexnum;++i) //初始化邻接矩阵,边的权值均为Maxint
for(j=0;j<G.vexnum;++j)
G.arcs[i][j]=Maxint;
for(k=0;k<G.arcnum;++k) //构造邻接矩阵
{
cin>>v1>>v2>>w; //输入一条边依附的顶点及权值
i=LocateVex(G,v1); j=LocateVex(G,v2); //确定v1,v1在G中的位置,即顶点数组的下标
G.arcs[i][j]=w; //边<v1,v2>的权值置为w
G.arcs[j][i]=G.arcs[i][j]; //置<v1,v2>的对称边<v2,v1>的权值为w
}
return OK;
}
那么怎样找到上面算法的i 和 j 呢,即 v1 和 v2 的下标
【算法分析】
时间复杂的为O(n^2)
既然我们知道了怎样用邻接矩阵表示法创建无向网,其实无向图、有向网、有向图我们也就知道怎样创建了,只需要对创建无向网的算法步骤稍作改变
7、邻接矩阵优点和缺点
优点:
-
直观、简单、好理解
-
方便检查任意一对顶点间是否存在边
-
方便找任一顶点的所有“邻接点”(有边直接相连的顶点)
-
方便计算任一顶点的“度”
缺点: -
不便于增加和删除顶点
-
浪费空间—存稀疏图(点很多、边很少)有大量无效元素,空间复杂度
O(n^2)
-
浪费时间—统计一共多少条边,需要扫描邻接矩阵所有元素,时间复杂度
O(n^2)
8、邻接矩阵表示法创建无向网代码实现
#include<iostream>
using namespace std;
#define OK 1
#define Maxint 32767
typedef int status ;
typedef struct
{
char vexs[100];
int arcs[100][100];
int vexnum,arcnum;
}AMGraphy;
status LocateVex(AMGraphy G,int u);
status CreateUDN(AMGraphy &G);
int main()
{
AMGraphy G;
CreateUDN(G);
cout<<"邻接矩阵为:"<<endl;
for(int i=0;i<G.vexnum;i++)
{
for(int j=0;j<G.vexnum;j++)
cout<<G.arcs[i][j]<<" ";
cout<<endl;
}
return 0;
}
status CreateUDN(AMGraphy &G)
{//采用邻接矩阵表示法,创建无向网G
cin>>G.vexnum>>G.arcnum; //输入总顶点数,总边数
for(int i=0;i<G.vexnum;i++)
cin>>G.vexs[i]; //依次输入点的信息
for(int i=0;i<G.vexnum;i++) //初始化邻接矩阵,边的权值均为Maxint
for(int j=0;j<G.vexnum;j++)
G.arcs[i][j]=Maxint;
for(int k=0;k<G.arcnum;k++) //构造邻接矩阵
{
char v1,v2;
int w;
cin>>v1>>v2>>w; //输入一条边依附的顶点及权值
int i=LocateVex(G,v1);
int j=LocateVex(G,v2); //确定v1,v1在G中的位置,即顶点数组的下标
G.arcs[i][j]=w; //边<v1,v2>的权值置为w
G.arcs[j][i]=G.arcs[i][j]; //置<v1,v2>的对称边<v2,v1>的权值为w
}
return OK;
}
status LocateVex(AMGraphy G,int u)
{
int i;
for(i=0;i<G.vexnum;i++)
if(u==G.vexs[i]) return i;
return -1;
}