目录
图的存储结构
邻接矩阵
邻接矩阵表示法
1、邻接矩阵:表示顶点之间相连关系的矩阵
2、图和网的矩阵表示:
图的矩阵用1和0来区分
网的矩阵用权值和无穷来区分
3、存储表示
#include<bits/stdc++.h> using namespace std; #define MAXINT 32767//为什么无穷是32767?? #define MAXNUM 110 //最大顶点数 #define OK 1 //成功标识 #define ERROR 0 //失败标识 typedef int status; //Status是函数的类型,其值是函数结果状态代码,如OK等 typedef struct { char vexs[MAXNUM];//顶点表(vertex-顶点) int arcs[MAXNUM][MAXNUM];//邻接矩阵 int vex,arc;//图的当前点数和边数 }AMGraph;
采用邻接矩阵表示法创建无向网
【算法步骤】
①输入总顶点数和总边数
②依次输入点的信息并将其存人顶点表中
③初始化邻接矩阵,使每个权值初始化为 极大值。
④构造邻接矩阵。依次输入每条边依附的顶点和其权值,确定两个顶点在图中的位置之后,使相应边赋予相应的权他直,同时使其对称边赋予相同的权值。status Creat(AMGraph &G) { cin>>G.vex>>G.arc;//输入总定点数,总边数 for(int i=0;i<G.vex;i++) cin>>G.vexs[i];//输入点 //初始化邻接矩阵 for(int i=0;i<G.vex;i++) for(int j=0;j<G.vex;j++) { G.arcs[i][j]=MAXINT; } for(int k=0;k<G.arc;k++) { cin>>v1>>v2>>w; int i=Locate(G,v1); int j=Locate(G,v2); G.arcs[i][j]=w; G.arcs[j][i]=w; } return OK; }
采用邻接矩阵表示法创建无向图
若要建立无向图,只需对上述算法做两处小的的改动:一是初始化邻接矩阵时,将边的权值均初始化为0;
二是构造邻接矩阵时,将权值w改为常量值1即可。
同样,将该算法稍做修改即可建立一个有向网或有向图。
status Creat(AMGraph &G) { cin>>G.vex>>G.arc;//输入总定点数,总边数 for(int i=0;i<G.vex;i++) cin>>G.vexs[i];//输入点 //初始化邻接矩阵 for(int i=0;i<G.vex;i++) for(int j=0;j<G.vex;j++) { G.arcs[i][j]=0; } for(int k=0;k<G.arc;k++) { cin>>v1>>v2; int i=Locate(G,v1); int j=Locate(G,v2); G.arcs[i][j]=1; G.arcs[j][i]=1; } return OK; }
邻接矩阵的优缺点
(1)优点
①便于判断两个顶点之间是否有边,即根据A[i][j]=0或1来判断。
②便于计算各个顶点的度。对于无向图,邻接矩阵第行元素之和就是顶点v的度;
对于有向图,第i行元素之和就是顶点v的出度,第i列元素之和就是顶点的入度。
(2)缺点①不便于增加和删除顶点
②不便于统计边的数目
③空间复杂度高。(如果是有向图,n个顶点需要n^2个单元存储边)
邻接表
邻接表表示法
邻接表(AdjacencyList)是图的一种链式存储结构。
1、在邻接表中,对图中每个顶点v建立一个单链表,与v相邻接的顶点放在这个链表中。
2、邻接表中每个单链表的第一个节点存放顶点。把这一节点看成链表的表头。
3、其余节点存放有关边的信息,这样邻接表便由两部分组成:表头节点表和边表。
(1)表头节点表:由所有表头节点以顺序结构的形式存储,以便可以随机访问任一顶点的边链表。表头节点包括数据域(data)和链域(firstarc)两部分。①数据域用于存储顶点v的名称或其他有关信息;
②链域用于指向链表中第一个节点(与顶点v,邻接的第一个邻接点)。
(2)边表:由表示图中顶点间关系的2n个边链表组成。边链表中边节点包括邻接点域(adjvex)、数据域(info)和链域(nextarc)3个部分。①邻接点域指示与顶点v邻接的点在图中的位置;
②数据域存储和边相关的信息,如权值等;
③链域指示与项点v邻接的下一条边的节点。
存储表示
#include<bits/stdc++.h> using namespace std; #define MAXINT 32767//为什么无穷是32767?? #define MAXNUM 110 //最大顶点数 #define OK 1 //成功标识 #define ERROR 0 //失败标识 typedef int status; //Status是函数的类型,其值是函数结果状态代码,如OK等 typedef struct Arcnode{//边表 int adj; struct Arcnode* next; }Arcnode; typedef struct Vnode{//表头节点表 char data; Arcnode *firstarc; }Vnode,AdjList[MAXNUM]; typedef struct { AdjList ver; int vexn,arcn;//图当前顶点数,边数 }AlGraph;
采用邻接表表示法创建无向图
【算法步骤】
①输入总顶点数和总边数。
②依次输入点的信息存人顶点表中,使每个表头节点的指针域初始化为
NULL
③创建邻接表。依次输入每条边依附的两个顶点 确定这两个顶点的序
号和j之后,将此边节点分别插人v和v对应的两个 边链表的头部。status Creat(AlGraph &G) { cin>>G.vex>>G.arc;//输入总定点数,总边数 for(int i=0;i<G.vex;i++) { cin>>G.ver[i].data ;//输入顶点 G.ver[i].firstarc=NULL; } for(int k=0;k<G.arc ;k++) { cin>>v1>>v2; int i=Locate(G,v1); int j=Locate(G,v2); Arcnode *p1,*p2; //将新节点p1插入顶点vi的边表头部 p1=new Arcnode; p1->adj =j; p1->next =G.ver[i].firstarc; G.ver[i].firstarc=p1; //将新节点p2插入顶点vj的边表头部 p2=new Arcnode; p2->adj =i; p2->next =G.ver[j].firstarc; G.ver[j].firstarc=p2; } return OK; }
邻接表的优缺点
(1)优点
①便于增加和删除顶点。
②便于统计边的数目,按顶点表顺序查找所有边表可得到边的数目。
③空间效率高。
(2)缺点
①不便于判断顶点之间是否有边,要判定v和v之间是否有边,就需查找第i个边表。
②不便于计算有向图各个顶点的度。