2026/1/1 13:18:16
网站建设
项目流程
建设部标准规范网站,wordpress竖直导航栏,大麦网的网站建设,个人网站建设的小清新图片邻接矩阵
顶点结构
用顺序表存顶点集#xff0c;每个顶点包含数据data#xff0c;顶点编号id#xff08;大部分情况下和顶点在数组中的下标对应#xff09;
struct Vertex{int id;DataType data;
};边结构
用边的两个顶点在顺序表中的索引表示边#xff0c;由于一条边包含…邻接矩阵顶点结构用顺序表存顶点集每个顶点包含数据data顶点编号id大部分情况下和顶点在数组中的下标对应struct Vertex{ int id; DataType data; };边结构用边的两个顶点在顺序表中的索引表示边由于一条边包含两个索引所以用一个二维数组来表示E集边存在就填1不存在就填0自己指向自己的边或INF不同顶点之间的边typedef int Edge; //表示边的存在状态0,1,INF图结构封装好顶点集和边集用vertexNum表示顶点个数edgeNum表示边的条数isDirect表示是否是有向图struct MGraph{ Vertex nodes[MaxNumber]; Edge edges[MaxNumber][MaxNumber]; int vertexNum; int edgeNum; bool isDirect; };初始化图把边集里面自己指向自己的边填为0不同顶点之间的边填为无穷大假设已确定所有顶点void initGraph(MGraph* graph,int vNum,bool isDirect,DataType vertex[]){ graph-vertexNumvNum; greph-edgeNum0; graph-isDirectisDirect; for(int i0;ivertexNum;i){ //初始化顶点集 graph-nodes[i].idi; graph-nodes[i].datavertex[i]; for(int j0;jvertexNum;j){ //初始化边集 if(ij)graph-edges[i][j]0; else graph-edges[i][j]INFINITY; } } }添加边假设边有权重weight若不是网络就填1边的起点为v1索引边的终点为v2索引若是无向图添加一条边要添加对应的相反的边void InsertEdge(MGraph* graph,int v1,int v2,int weight){ graph-edges[v1][v2]weight; if(!graph-isDirect){ graph-edges[v2][v1]weight; } graph-edgeNum; }邻接表边结构实际上是边的弧头和弧尾表示一条出度边包含边的权值weight如果是无权图就不需要顶点的编号弧头在数组中的下标id指向下一个弧头的指针nextstruct Edge{ int weight; int id; Edge* next; }顶点结构用顺序表存顶点每个顶点包含编号id顶点的数据data顶点的第一条出度边实际上是弧头fitstEdgestruct Vertex{ int id; Datatype data; Edge* firstEdge; }图结构包含顶点集数组V顶点数量vertexNum边数量edgeNum是否是有向图isDirectstruct LGreaph{ Vertex* nodes; int vertexNum; int edgeNum; bool isDirect; }初始化图给顺序表中的顶点初始化data和idfirstEdge初始化为NULLvoid initGraph(LGraph* graph,bool isDirect,int vNum,int edgeNum,DataType vertex[]){ graph-isDirectisDirct; graph-vertexNumvNum; graph-edgeNum0; for(int i0;igraph-vertexNum;i){ //初始化顶点集 graph-nodes[i].idi; graph-nodes[i].datavertex[i]; graph-nodes[i].firstEdgeNULL; } }添加边用头插法插在出度链表的表头维护edgeNum如果是无向图需要添加相反的出度边Edge* createEdge(int w,int v){ Edge* emalloc(sizeof(Edge)); e-weightw; e-idv; e-nextNULL; return e; } void InsertEdge(LGraph* graph,int weight,int v1,int v2){ Edge* ecreateEdge(weight,v2); e-nextgraph-nodes[v1].firstEdge; graph-nodes[v1].firstEdgee; graph-edgeNum; if(!graph-isDirect){ //添加相反的出度边 ecreateEdge(weight,v1); e-nextgraph-nodes[v2].firstEdge; graph-nodes[v2].firstEdgee; } }缺点不方便统计入度十字链表CrossGraph主要解决有向图若用逆邻接表存有向图有n条边就需要存2n个边结构用十字链表存有向图有n条边只需要存n个边结构边结构一条边含弧尾节点的编号tail弧头节点的编号head指向tail下一条出度边的指针tailNext指向head下一条入度边的指针headNext边的权重weightstruct Edge{ int tail; Edge* tailNext; int head; Edge* headNext; }顶点结构一个顶点含顶点编号id顶点数据data指向第一条入度边的指针firtstIn指向第一条出度边的指针firstOutstruct Vertex{ int id; DataType data; Edge* firstIn; Edge* firstOut; }图结构用顺序表存储顶点集struct CGraph{ int vertexNum; int edgeNum; Vertex* nodes; }初始化图void initGraph(CGraph* graph,int vNum,DataType vertex[]){ graph-vertexNumvNum; graph-edgeNum0; for(int i0;igraph-vertexNum;i){ //初始化顶点结构 graph-idi; graph-nodes[i].datavertex[i]; graph-nodes[i].firstInnullptr; graph-nodes[i].firstOutnullptr; } }添加边用头插法插入入度链表和出度链表void InsertEdge(CGraph* graph,int t,int h,int w){ Edge* e(Edge*)Edge(sizeof(Edge)); if(!e)return; graph-edgeNum; e-tailt; e-headh; e-weightw; //头插法插入出度边 e-tailNextgraph-nodes[e-tail]-firstOut; graph-nodes[e-tail]-firstOute; //头查法插入入度边 e-headNextgraph-nodes[e-head]-firstIn; graph-nodes[e-head]-firstIne; }遍历所有出度只需要从firstOut开始沿着tailNext遍历到NULLvoid traversalOut(CGraph* graph,int v){ Edge* pgraph-nodes[v]-firstOut; while(p){ visit(p); //访问行为 pp-tailNext; } }遍历入度同理遍历所有入度只需要从firstIn开始沿着headNext遍历到NULLvoid traversalIn(CGraph* graph,int v){ Edge* pgraph-nodes[v]-firstIn; while(p){ visit(p); //访问行为 pp-headNext; } }