邻接矩阵存储无向图
没有进行矩阵压缩
没有遍历算法
仅邻接矩阵存储无向图的基本代码实现
/* 无向图的基本操作包括: 1. 初始化图:创建一个空的图数据结构,并初始化图的顶点数和边数。 2. 创建图 3. 判断邻接矩阵是否合法 4. 添加顶点:向图中添加一个新的顶点。 5. 添加边:在图中添加一条连接两个顶点的边。 6. 删除顶点:从图中删除一个指定的顶点,同时删除与该顶点相关联的边。 7. 删除边:从图中删除一条指定的边。 8. 判断顶点是否存在:检查图中是否存在指定的顶点。 9. 判断边是否存在:检查图中是否存在指定的边。 10. 获取顶点的邻居顶点:获取与指定顶点直接相连的顶点集合。 11. 获取顶点的度:计算指定顶点的度,即入度和出度的总和。 12. 打印邻接矩阵 这些基本操作可以帮助我们在图中进行顶点和边的增删查改,以及进行图的遍历和分析。 具体实现会根据不同的图的表示方式和算法来进行。 */ #include <stdlib.h> #include <stdio.h> #define MaxVertexNum 20 typedef int VertexType; typedef int EdgeType; typedef struct{ VertexType Vex[MaxVertexNum]; //存储顶点 EdgeType Edge[MaxVertexNum][MaxVertexNum]; //存储边 int VexNum; //顶点数 int EdgeNum; //边数 }Graph; //1.初始化图 void InitGraph(Graph &G) { int i,j; for(i=0;i<MaxVertexNum;i++) { G.Vex[i]=0; //顶点值初始化为0 for(j=0;j<MaxVertexNum;j++) G.Edge[i][j]=0; //邻接矩阵中的元素初始化为0 } G.VexNum=0; //顶点个数初始化为0 G.EdgeNum=0; //边数初始化为0 } //2.创建图 bool CreateGraph(Graph &G) { int MaxNum,i,j; printf("图的顶点个数为:"); scanf("%d",&MaxNum); if(MaxNum<=0) return false; G.VexNum=MaxNum; printf("输入顶点值:\n"); for(i=0;i<G.VexNum;i++) scanf("%d",&G.Vex[i]); printf("输入(0/1)到邻接矩阵:\n"); int count=0; for(i=0;i<G.VexNum;i++) { for(j=0;j<G.VexNum;j++) { scanf("%d",&G.Edge[i][j]); if(G.Edge[i][j]==1) count++; } } G.EdgeNum=count/2; } //3.判断邻接矩阵是否合法 bool isValid(Graph G) { //判断是否为空 if(G.VexNum<=0) { printf("图空\n"); return false; } //判断对角线元素是否非0 for(int i=0;i<G.VexNum;i++) { if(G.Edge[i][i]!=0) { printf("对角线元素非0\n"); return false; } } //判断矩阵是否对称 for(int i=0;i<G.VexNum;i++) { for(int j=0;j<G.VexNum;j++) { if(G.Edge[i][j]!=G.Edge[j][i]) { printf("矩阵不对称\n"); return false; } } } return true; } //4.添加顶点 bool AddVertex(Graph &G,VertexType ver) { if(G.VexNum==MaxVertexNum) return false; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver) return false; } G.Vex[G.VexNum]=ver; G.VexNum++; for(int i=0;i<G.VexNum;i++) //更新邻接矩阵 { G.Edge[i][G.VexNum-1]=0; G.Edge[G.VexNum-1][i]=0; } return true; } //5.添加边 bool AddEdge(Graph &G,VertexType ver1,VertexType ver2)//传入的是顶点值 { int v1=-1; int v2=-1; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver1) v1=i; if(G.Vex[i]==ver2) v2=i; if(v1>=0 && v2>=0) //提前结束 break; } if(v1<0 || v2<0) return false; //顶点不存在 if(G.Edge[v1][v2]==1) return false; //边已存在 G.Edge[v1][v2]=1; G.Edge[v2][v1]=1; G.EdgeNum++; return true; } //6.删除顶点 bool DeleteVertex(Graph &G,VertexType ver)//传入的是顶点值 { int v=-1; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver) { v=i; break; } } if(v<0 || v>=G.VexNum) return false; //删除相应的边 for(int i=v;i<G.VexNum-1;i++) { for(int j=0;j<G.VexNum;j++) { G.Edge[i][j]=G.Edge[i+1][j]; G.Edge[j][i]=G.Edge[j][i+1]; } } //删除顶点 for(int i=v;i<G.VexNum-1;i++) G.Vex[i]=G.Vex[i+1]; G.VexNum--; //更新边数 int count=0; for(int i=0;i<G.VexNum;i++) for(int j=0;j<G.VexNum;j++) if(G.Edge[i][j]==1 || G.Edge[j][i]==1) count++; G.EdgeNum=count/2; return true; } //7.删除边 bool DeleteEdge(Graph &G,VertexType ver1,VertexType ver2) { int v1=-1; int v2=-1; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver1) v1=i; if(G.Vex[i]==ver2) v2=i; if(v1>=0 && v2>=0) //提前结束 break; } if(v1<0 || v2<0) return false; if(G.Edge[v1][v2]==0) return false; else { G.Edge[v1][v2]=0; G.Edge[v2][v1]=0; G.EdgeNum--; } return true; } //8.判断顶点是否存在 bool ExistVertex(Graph G,VertexType ver)//传入的是顶点值,不是下标 { for(int i=0;i<G.VexNum;i++) if(G.Vex[i]==ver) return true; return false; } //9.判断边是否存在 bool ExistEdge(Graph G,VertexType ver1,VertexType ver2)//传入的是顶点值,不是下标 { int v1,v2; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver1) v1=i; if(G.Vex[i]==ver2) v2=i; if(v1>=0 && v2>=0) //提前结束 break; } if(G.Edge[v1][v2]==0) return false; return true; } //10.获取顶点的邻居顶点 bool GetNeiborVertex(Graph G,VertexType ver) { int v=-1; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver) { v=i; break; } } if(v==-1) { printf("顶点不存在\n"); return false; } printf("%d的邻居顶点为:",ver); for(int i=0;i<G.VexNum;i++) { if(G.Edge[v][i]==1) printf("%d ",G.Vex[i]); } return true; } //11.获取顶点的度 int GetDegree(Graph G,VertexType ver) //注意v是数组下标 { int v=-1; int degree=0; for(int i=0;i<G.VexNum;i++) { if(G.Vex[i]==ver) { v=i; break; } } for(int i=0;i<G.VexNum;i++) { if(G.Edge[v][i]==1) degree++; } return degree; } //12.打印邻接矩阵 void DisplayGraph(Graph G) { int i,j; printf("顶点结点:\n"); for(i=0;i<G.VexNum;i++) { printf("%d ",G.Vex[i]); } printf("\n"); printf("邻接矩阵:\n"); for(i=0;i<G.VexNum;i++) { for(j=0;j<G.VexNum;j++) { printf("%d ",G.Edge[i][j]); if(j==G.VexNum-1) printf("\n"); } } /* for(int i=0;i<G.VexNum;i++) { for(int j=0;j<G.VexNum;j++) { if(G.Edge[i][j]==1 || G.Edge[j][i]==1) G.EdgeNum++; } } */ printf("图的边数为:%d\n",G.EdgeNum); } int main() { Graph G; InitGraph(G); CreateGraph(G); if(isValid(G)) { DisplayGraph(G); // printf("顶点1的度为%d\n",GetDegree(G,1)); } // DeleteVertex(G,1); // DisplayGraph(G); // DeleteEdge(G,1,2); // DisplayGraph(G); AddVertex(G,5); DisplayGraph(G); AddEdge(G,5,1); AddEdge(G,5,2); AddEdge(G,5,3); AddEdge(G,5,4); DisplayGraph(G); /* if(ExistVertex(G,2)) printf("顶点存在\n"); else printf("顶点不存在\n"); if(ExistEdge(G,2,3)) printf("边存在\n"); else printf("边不存在\n"); */ // GetNeiborVertex(G,2); return 0; }