存储方式:在这里介绍邻接表和邻接矩阵的结构,其他存储结构方式考的较少,不在这里一一赘述。
存储方式
邻接矩阵:
邻接矩阵即可存储无向图也可存储有向图,在稠密图中非常适用
结构体:
//邻接矩阵
struct MGraph{
//储存的顶点表
char vex[MaxSize];
//路径矩阵
int edge[MaxSize][MaxSize];
//存储顶点与边的个数
int vexnum,arcnum;
};
带权结构体
//带权重的邻接矩阵
struct MGraphW{
//储存的顶点表
char vex[MaxSize];
//路径矩阵,只不过改成权重了
int weight[MaxSize][MaxSize];
//存储顶点与边的个数
int vexnum,arcnum;
};
邻接表:
邻接表既可存储有向图也可存储无向图,需要注意的是邻接表是不唯一的。因为链接到一个顶点的链表排序是可以不同的。
结构体:
//邻接表结构体
struct ArcNode{
int adjvex; //指向顶点
struct archNode *next; //下一个节点位置
int weight; //权重
};
struct VNode{
char value; //顶点值
struct archNode *first; //指向的第一个节点
};
struct AdGraph{
VNode vertices[MaxSize]; //列表
int vexnum,arcnum; //顶点数和边数
};
十字链表:
主要存储有向图,在这里不赘述,读者知道即可,感兴趣可以参考相关资料。
邻接多重表:
主要存储无相图,相关内容同上
使用邻接表和邻接矩阵创建图:
邻接矩阵存储有向图:
不带权重:
//创建有向图
MGraph createMGraphX(){
//创建图
MGraph G;
//输入边与顶点的个数
scanf("%d,%d",&G.vexnum,&G.arcnum);
//初始化邻接矩阵全部置零
for(int i=0;i<G.vexnum,i++){
for(int j=0;j<G.vexnum,j++){
G.edge[i][j] = 0;
}
}
//边的创立
int v1,v2;
//输入有边的两个顶点
for(int i=0;i<G.arcnum;i++){
scanf("%d,%d",&v1,&v2);
G.edge[v1][v2] = 1;
}
return G;
}
带权重:
//创建带权重的有向图
MGraphW createMGWX(){
MGraphW G;
scanf("%d,%d",&G.arcnum,&G.vexnum);
for(int i=0;i<G.vexnum;i++){
for(int j=0;j<G.vexnum;j++){
G.weight[i][j] = INF;
}
}
int a,b,w;
for(int i=0;i<G.arcnum;i++){
scanf("%d,%d,%d",&a,&b,&w);
G.weight[a][b] = w;
}
return G;
}
邻接矩阵存储无向图:
不带权:
//创建无向图
MGraph createGraph(){
MGraph G;
scanf("%d,%d",&G.vexnum,&G.arcnum);
for(int i=0;i<G.vexnum;i++){
for(int j=0;j<G.vexnum;j++){
G.edge[i][j]=0;
}
}
int a,b;
for(in i=0;i<G.arcnum;i++){
scanf("%d,%d",&a,&b);
G.edge[a][b] = 1;
G.edge[b][a] = 1;
}
return G;
}
带权:
//创建无向带权图
MGraphW createMGW(){
MGraphW G;
scanf("%d,%d",&G.arcnum,&G.vexnum);
for(int i=0;i<G.vexnum;i++){
for(int j=0;j<G.vexnum;j++){
G.weight[i][j] = INF;
}
}
int a,b,w;
for(int i=0;i<G.arcnum;i++){
scanf("%d,%d,%d",&a,&b,&w);
G.weight[a][b] = w;
G.weight[b][a] = w;
}
return G;
}
邻接表(带权):
//创建邻接表
AdGraph createAdGraph(){
//创建图
AdGraph G;
//p代表前一个结点 q代表工作结点
ArcNode *p,*q;
//三个变量 n代表节点的边数的个数 a代表顶点下标 w代表权重
int n,a,w;
//输入总顶点数与边数
scanf("%d,%d",&G.vexnum,&G.arcnum);
//遍历输入
for(int i=0;i<G.vexnum;i++){
//输入点的值和此点的边数
scanf("%c,%d",&G.vertices[i].value,n);
//设置起始顶点置空
G.vertices[i].first = NULL;
//顶点链上边
for(int j=0;j<n;j++){
q = (ArcNode*)malloc(sizeof(ArcNode));
//输入指向的顶点 权重
scanf("%d,%d",&a,&w);
q->adjvex = a;
q->weight = w;
//挂载结点
if(!G.vertices[i].first){
G.vertices[i].first = q;
p = q;
}else{
p->next = q;
p = q;
}
}
//置空工作节点,留给下一个结点
p = NULL;
}
return G;
}
常见考法:
邻接矩阵求出度入度:
//求解顶点的入度与出度
int getInDegree(MGraph g,int v){
int degree=0;
for(int i=0;i<g.vexnum;i++){
if(g.edge[i][v]!=0){
degree++;
}
}
}
int getOutDegree(MGraph g,int v){
int degree=0;
for(int i=0;i<g.vexnum;i++){
if(g.edge[v][i]!=0)degree++;
}
return degree;
}
求邻接矩阵的边数:
//求解有向图的边数
int getEdgeNums(MGraph g){
int edges = 0;
for(int i=0;i<g.vexnum;i++){
for(int j=0;j<g.vexnum;j++){
if(g.edge[i][j]!=1)edges++;
}
}
return edges;
}
求邻接表的出度入度:
//求出度
int getOutDegreeFromAdGraph(AdGraph g,int v){
int degree = 0;
ArcNode *p = g.vertices[v].first;
while(p){
p = p->next;
degree++;
}
return degree;
}
//求入度
int getInDegreeFromAdGraph(AdGraph g,int v){
int degree = 0;
ArcNode *p = NULL;
for(int i=0;i<g.vexnum;i++){
p = g.vertices[i].first;
while(p){
if(p->adjvex == v)degree++;
p = p->next;
}
}
return degree;
}
邻接矩阵与邻接表之间的转化:
//邻接表 -> 邻接矩阵
MGraph AtoM(AdGraph g){
MGraph m;
m.arcnum = g.arcnum;
m.vexnum = g.vexnum;
for(int i=0;i<m.vexnum;i++){
for(int j=0;j<m.vexnum;j++){
m.edge[i][j] = 0;
}
}
ArcNode *p = NULL;
for(int i=0;i<vexnum;i++){
p = g.vertices[i].first;
while(p){
int v = p->adjvex;
m.edge[i][v]=1;
p = p->next;
}
}
return m;
}
//矩阵->表
AdGraph MtoA(MGraph g){
AdGraph a;
ArcNode *p,*q;
a.arcnum = g.arcnum;
a.vexnum = g.vexnum;
for(int i=0;i<g.vexnum;i++){
a.vertices[i].value = g.vex[i];
a.vertices[i].first = NULL;
for(int j=0;j<g.vexnum;j++){
if(g.edge[i][j]!=0){
q = (ArcNode*)malloc(sizeof(ArchNode));
q->next = NULL;
q->adjvex = g.vex[j];
//权重
q->weight = g.edge[i][j];
if(a.vertices.first[i]==NULL){
a.vertices.first[i] = q;
p = q;
}else{
p->next = q;
p = q
}
}
}
}
return a;
}
2012统考真题,是否存在EL路径:
int isExistEl(MGraph G){
int n = 0,degree = 0;
for(int i=0;i<G.vexnum;i++){
degree = 0;
for(int j=0;j<G.vexnum;j++){
if(G.edge[i][j]!=0){
degree++;
}
}
if(degree%2!=0)n++;
}
if(n==0 || n==2)return 1;
else return 0;
}
以上代码仅供参考,如有错误恳请指正!谢谢~