图的存储结构
1.邻接矩阵(数组表示法)的存储表示
用两个数组分别存储顶点表和邻接矩阵
#define MaxInt 32767 //表示极大值,即∞
#define MVNum 100 //最大顶点数
typedef char VerTexType; //设顶点的数据类型为字符型
typedef int ArcType; //设边的权值类型为字符型
typedef struct{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前点数和边数
}AMGraph; //Adjacency Matrix Graph
邻接矩阵创建无向图
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) //初始化邻接矩阵
for(j=0;j<G.vexnum;++i)
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和v2在G中的位置
G.arc[i][j]=w;
G.arc[j][i]=G.arc[i][j];
}
return OK
int LocateVex(AMGraph G,VerTexType u){//在图中查找顶点u,存在则返回顶点表中的下标,否则返回-1
int i;
for(i=0;i<G.vexnum;++i)
if(u==G.vex[i]) return i;
return -1;
}
邻接矩阵好处:
-
直观、简单
-
方便检查任意一对顶点间是否存在边
-
方便找任一顶点的所有“邻接点”
-
方便计算任一顶点的度
- 无向图:对应行(列)非0元素个数
- 有向图:对应行非0元素的个数是“出度”;对应列非0元素的个数是“入度”。
缺点:
-
不便于增加和删除顶点
-
浪费空间
-
浪费时间——统计稀疏图中有多少边
2.邻接表(链式)
头结点(存放顶点),表结点
typedef struct VNode{ //表头结点结构
VerTexType data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNUM];
#define MVNum 100 //最大顶点数
typedef struct ArcNode{ //弧(边)的结点结构
int adjvex; //该边所指向的顶点位置
struct ArcNode *nextarc; //指向下一条边的指针
OtherInfo info; //和边相关的信息
}ArcNode;
typedef struct{ //图的结构定义
AdjList vertices; //存放多个顶点
int vexnum,arcnum; //图的当前顶点数和弧数
}ALGraph;
采用邻接表表示法创建无向网
Status CreateUDG(ALGraph &G){
cin>>G.vexnum>>arcnum;//输入总顶点数,总边数
for(i=0;i<G.vexnum;++i){ //输入各点,构造表头节点表
cin>>G.vertices[i].data; //输入各顶点值
G.vertices[i].firstarc=NULL;//初始化表头结点的指针域
}
for(k=0;k<G.arcnum;++k){ //输入各边,构造邻接表
cin>>v1>>v2; //输入一条边依附的两个顶点
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p1=new ArcNode; //生成一个新的边界点*p1
p1->adjvex=j; //邻接点序号为j
p1->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p1;//将新结点*p1插入顶点vi的边表头部
p2=new ArcNode;//生成另一个对称的新的边界点*p2
p2->adjvex=i;
p2->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p2;
区别:
1.对于任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但邻接表不唯一(连接次序与顶点编号无关)。
2.邻接矩阵的空间复杂度为O(n^2),而邻接表的空间复杂度为O(n+e)
3.用途:邻接矩阵多用于稠密图,而邻接表多用于稀疏图。
十字链表:解决有向图求结点的度困难
邻接多重表:解决无向图每条边都要存储两遍