图的存储结构之邻接表
邻接表由一个一维数组(顶点表)和一个单链表(边表)组成。
顶点表由数据域和指针域组成,数据域存储顶点信息,指针域指向第一个邻接点。
边表由adjvex和next两个域组成,若需要权值信息可增加weight域,adjvex存储某顶点的邻接点在顶点表中的下表,next则存储指向边表中下一个结点的指针。
基本如下图所示:
代码(来源于《大话数据结构》):
AdjLinkGraph.h
#pragma once #define MAXVEX 20 typedef char VertexType; //顶点类型应由用户定义 typedef int EdgeType; //边上的权值类型应由用户定义 typedef struct EdgeNode //边表结点 { int adjvex; //邻接点域,存储该顶点对应的下标 EdgeType weight; //用于存储权值,对于非网图可以不需要 struct EdgeNode *next; //链域,指向下一个邻接点 }EdgeNode; typedef struct VertexNode //顶点表结点 { VertexType data; //顶点域 EdgeNode *firstedge; //边表头指针 }VertextNode, AdjList[MAXVEX]; typedef struct { AdjList adjList; int numVertexes, numEdges; //图中当前顶点数和边数 }GraphAdjList; void CreateALGraph(GraphAdjList *G);
AdjLinkGraph.cpp
#include "stdafx.h" #include "adjLinkGraph.h" #include <cstdlib> void CreateALGraph(GraphAdjList *G) { int i, j, k; EdgeNode *e; printf("输入顶点数和边数:\n"); scanf_s("%d,%d", &G->numVertexes, &G->numEdges); for (i = 0; i < G->numVertexes; i++) { printf("输入顶点数据:\n"); scanf_s("%d", &G->adjList[i].data); G->adjList[i].firstedge = NULL; } for (k = 0; k < G->numEdges; k++) { printf("输入边(vi,vj)上的顶点序号:\n"); scanf_s("%d,%d", &i, &j); e = (EdgeNode *)malloc(sizeof(EdgeNode)); e->adjvex = j; e->next = G->adjList[i].firstedge; G->adjList[i].firstedge = e; //不断更新firstedge,用e->next链接更新过的firstedge e = (EdgeNode *)malloc(sizeof(EdgeNode)); e->adjvex = i; e->next = G->adjList[i].firstedge; G->adjList[j].firstedge = e; } }
调用:
// AdjecentTable.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "adjLinkGraph.h" int main() { GraphAdjList G; CreateALGraph(&G); printf("邻接表创建成功!"); return 0; }
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决