杂谈:最近清明小长假,好好的放松了一下。节前 和 节后 都有点 松懈。不好,不好。贵在坚持。加油。
图的邻接矩阵表示法是用 两个数组 来表示 图的数据结构。一个是顶点数组,另一个是邻接矩阵数组。邻接矩阵 里存放着 顶点的关系。
用邻接矩阵表示图,在 看 顶点之间 是否有边,或者 求顶点的度等操作时比较简单。但空间浪费巨大,在插入,删除 顶点 和边 操作时 需要 移动大量数据,造成不便。所以在插入删除比较多,节点数比较多的时候 不宜 使用这种结构。
下面上代码:
源代码网盘地址:点击打开链接
// MGraph2.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <climits> #include <cstring> #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20 enum E_State { E_State_Error = 0, E_State_Ok = 1, }; enum E_Graph_Kind { DG = 0,//有向图 DN,//有向网 UDG,//无向图 UDN,//无向网 }; //边(弧)单元 typedef struct ArcCell { int adj;//表示顶点的关系类型,对于无权图,0,1表示是否相邻,对于有权图,表示权值类型 char * info;//边,弧其余信息. }AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //定义图 struct MGraph { char vexs[MAX_VERTEX_NUM];//顶点集 AdjMatrix arcs;//图的邻接矩阵 int vexNum,arcNum; E_Graph_Kind kind; }; int graphLocation(MGraph graph,char vex); void createDG(MGraph * graph); void createDN(MGraph * graph); void createUDG(MGraph * graph); void createUDN(MGraph * graph); void graphCreate(MGraph * graph){ E_Graph_Kind kind; printf("请输入要创建的图的类型(有向图:0,有向网:1,无向图:2,无向网:3)\n"); scanf("%d",&kind); switch (kind){ case DG: createDG(graph); break; case DN: createDN(graph); break; case UDG: createUDG(graph); break; case UDN: createUDN(graph); break; default: break; } } //返回顶点vex的第一个邻接点 char firstAdjVex(MGraph graph,char vex){ int location = graphLocation(graph,vex); int i = 0; for (; i < graph.vexNum; i++){ if ((graph.kind == DG || graph.kind == UDG) && graph.arcs[location][i].adj == 1){ return graph.vexs[i]; } else if((graph.kind == DN || graph.kind == UDN) && graph.arcs[location][i].adj != INFINITY){ return graph.vexs[i]; } } return ' '; } //返回顶点vex1 相对于 vex2的下一个邻接点. char nextAdjVex(MGraph graph,char vex1,char vex2){ int location1 = graphLocation(graph,vex1); int location2 = graphLocation(graph,vex2); int i = location2+1; for (; i < graph.vexNum; i++){ if ((graph.kind == DG || graph.kind == UDG) && graph.arcs[location1][i].adj == 1){ return graph.vexs[i]; } else if((graph.kind == DN || graph.kind == UDN) && graph.arcs[location1][i].adj != INFINITY){ return graph.vexs[i]; } } return ' '; } //查找顶点的位置 int graphLocation(MGraph graph,char vex){ for (int i = 0; i < graph.vexNum; i++){ if (graph.vexs[i] == vex){ return i; } } return -1; } //创建图 子函数 //有向图 void createDG(MGraph * graph){ graph->kind = DG; printf("请输入顶点数,边(弧)数\n"); scanf("%d%d%*c",&graph->vexNum,&graph->arcNum); //初始化邻接矩阵 for (int i = 0; i < MAX_VERTEX_NUM; i++){ for (int j = 0; j < MAX_VERTEX_NUM; j++){ graph->arcs[i][j].adj = 0; graph->arcs[i][j].info = NULL; } } //构造顶点集 printf("请输入顶点集\n"); for (int i = 0; i < graph->vexNum; i++){ scanf("%c",&graph->vexs[i]); } //构造顶点关系 fflush(stdin); printf("请输入顶点的关系\n"); for (int i = 0; i < graph->arcNum; i++){ char vex1,vex2; scanf("%c%c%*c",&vex1,&vex2); int location1 = graphLocation(*graph,vex1); int location2 = graphLocation(*graph,vex2); graph->arcs[location1][location2].adj = 1; } } //有向网 void createDN(MGraph * graph){ graph->kind = DN; printf("请输入顶点数,边(弧)数\n"); scanf("%d%d%*c",&graph->vexNum,&graph->arcNum); //初始化邻接矩阵 for (int i = 0; i < MAX_VERTEX_NUM; i++){ for (int j = 0; j < MAX_VERTEX_NUM; j++){ graph->arcs[i][j].adj = INFINITY; graph->arcs[i][j].info = NULL; } } //构造顶点集 printf("请输入顶点集\n"); for (int i = 0; i < graph->vexNum; i++){ scanf("%c",&graph->vexs[i]); } //构造顶点关系 fflush(stdin); printf("请输入顶点的关系\n"); for (int i = 0; i < graph->arcNum; i++){ char vex1,vex2; int weight; scanf("%c%c%d%*c",&vex1,&vex2,&weight); int location1 = graphLocation(*graph,vex1); int location2 = graphLocation(*graph,vex2); graph->arcs[location1][location2].adj = weight; } } //无向图 void createUDG(MGraph * graph){ graph->kind = UDG; printf("请输入顶点数,边(弧)数\n"); scanf("%d%d%*c",&graph->vexNum,&graph->arcNum); //初始化邻接矩阵 for (int i = 0; i < MAX_VERTEX_NUM; i++){ for (int j = 0; j < MAX_VERTEX_NUM; j++){ graph->arcs[i][j].adj = 0; graph->arcs[i][j].info = NULL; } } //构造顶点集 printf("请输入顶点集\n"); for (int i = 0; i < graph->vexNum; i++){ scanf("%c",&graph->vexs[i]); } fflush(stdin); //构造顶点关系 printf("请输入顶点的关系\n"); for (int i = 0; i < graph->arcNum; i++){ char vex1,vex2; scanf("%c%c%*c",&vex1,&vex2); int location1 = graphLocation(*graph,vex1); int location2 = graphLocation(*graph,vex2); graph->arcs[location1][location2].adj = graph->arcs[location2][location1].adj = 1; } } //无向网 void createUDN(MGraph * graph){ graph->kind = UDN; printf("请输入顶点数,边(弧)数\n"); scanf("%d%d%*c",&graph->vexNum,&graph->arcNum); //初始化邻接矩阵 for (int i = 0; i < MAX_VERTEX_NUM; i++){ for (int j = 0; j < MAX_VERTEX_NUM; j++){ graph->arcs[i][j].adj = INFINITY; graph->arcs[i][j].info = NULL; } } //构造顶点集 printf("请输入顶点集\n"); for (int i = 0; i < graph->vexNum; i++){ scanf("%c",&graph->vexs[i]); } //构造顶点关系 fflush(stdin); printf("请输入顶点的关系\n"); for (int i = 0; i < graph->arcNum; i++){ char vex1,vex2; int weight; scanf("%c%c%d%*c",&vex1,&vex2,&weight); int location1 = graphLocation(*graph,vex1); int location2 = graphLocation(*graph,vex2); graph->arcs[location1][location2].adj =graph->arcs[location2][location1].adj = weight; } } //查看顶点数据之间是否相邻 bool graphIsAdj(MGraph graph,char vex1,char vex2){ E_Graph_Kind kind = graph.kind; int weight = (kind == DG || kind == UDG) ? 0 : INFINITY; int location1 = graphLocation(graph,vex1); int location2 = graphLocation(graph,vex2); return graph.arcs[location1][location2].adj != weight ? true : false; } int graphDegree(MGraph graph,char vex){ int location = graphLocation(graph,vex); E_Graph_Kind kind = graph.kind; int weight = (kind == DG || kind == UDG) ? 0 : INFINITY; int degree = 0; for (int i = 0; i < graph.vexNum; i++){//计算行 if (graph.arcs[location][i].adj != weight){ degree++; } } for (int i = 0; i < graph.vexNum; i++){//计算列 if (graph.arcs[i][location].adj != weight){ degree++; } } if (kind == UDG || kind == UDN){ degree /= 2; } return degree; } //当有以下操作时,不适合 用邻接矩阵的方式来处理。 void insertVex(MGraph * graph,char vex){ graph->vexs[graph->vexNum++] = vex; } //需要移动很多元素. void deleteVex(MGraph * graph,char vex){ int location = graphLocation(*graph,vex); //删除顶点集 for (int i = location+1; i < graph->vexNum; i++){ graph->vexs[i-1] = graph->vexs[i]; } //计算删除的边(弧)数 graph->arcNum -= graphDegree(*graph,vex); //删除边(弧) //vex下面的上移 for (int i = location+1; i < graph->vexNum; i++){ for (int j = 0; j < graph->vexNum; j++){ graph->arcs[i-1][j] = graph->arcs[i][j]; } } //vex右边的左移 for (int i = location + 1; i < graph->vexNum; i++){ for (int j = 0; j < graph->vexNum; j++){ graph->arcs[j][i-1] = graph->arcs[j][i]; } } //清理垃圾数据(第vexNum行 和 第vexNum列) int maxVexNum = graph->vexNum; E_Graph_Kind kind = graph->kind; int weight = (kind == DG || kind == UDG) ? 0 : INFINITY; for (int i = 0; i < maxVexNum; i++){ graph->arcs[maxVexNum-1][i].adj = weight; graph->arcs[i][maxVexNum-1].adj = weight; } graph->vexNum--; } //插入边(弧) void insertArc(MGraph * graph,char vex1,char vex2,int weight){ int location1 = graphLocation(*graph,vex1); int location2 = graphLocation(*graph,vex2); E_Graph_Kind kind = graph->kind; if (kind == DG || kind == UDG){ graph->arcs[location1][location2].adj = 1; } else{ graph->arcs[location1][location2].adj = weight; } if (kind == UDG || kind == UDN) { graph->arcs[location2][location1].adj = graph->arcs[location1][location2].adj; } } //删除边(弧) void deleteArc(MGraph * graph,char vex1,char vex2){ int location1 = graphLocation(*graph,vex1); int location2 = graphLocation(*graph,vex2); E_Graph_Kind kind = graph->kind; if (kind == DG || kind == UDG){ graph->arcs[location1][location2].adj = 0; } else{ graph->arcs[location1][location2].adj = INFINITY; } if (kind == UDG || kind == UDN) { graph->arcs[location2][location1].adj = graph->arcs[location1][location2].adj; } } void printAdjMatrix(MGraph graph){ for (int i = 0; i < graph.vexNum; i++){ for (int j = 0; j < graph.vexNum; j++){ printf("%d\t",graph.arcs[i][j]); } printf("\n"); } } int _tmain(int argc, _TCHAR* argv[]) { MGraph graph; graphCreate(&graph); printAdjMatrix(graph); printf("图 有 %d个顶点,%d个边(弧)\n",graph.vexNum,graph.arcNum); char * isAdj = graphIsAdj(graph,'a','d')? "相邻":"不相邻"; int degree = graphDegree(graph,'c'); printf("a 和 d %s,c的度数是:%d\n",isAdj,degree); char vexFirst = firstAdjVex(graph,'c'); char vexNext = nextAdjVex(graph,'c','a'); printf("c的第一个邻接点是%c\nc的相对于a的下一个邻接点是%c\n",vexFirst,vexNext); insertVex(&graph,'e'); printf("插入节点e之后:\n"); printAdjMatrix(graph); printf("插入边(e,d)之后:\n"); insertArc(&graph,'e','d',1); printAdjMatrix(graph); printf("删除顶点c之后:\n"); deleteVex(&graph,'c'); printAdjMatrix(graph); deleteArc(&graph,'a','b'); printf("删除弧(a,b)之后:\n"); printAdjMatrix(graph); return 0; }
运行截图:
时间: 2024-11-06 06:42:11