邻接表=邻接链表。
我觉得,还是要自己写写,写出来,理解才会更深一点,以前眼高手低,不知其中厉害啊。
其实还是蛮有趣的!我觉得,还是要把数据结构学好,工具总是在变,但是思想才是最重要的。
代码的注释应该还是非常详细的,学这个,还是要结合书上的图,就是严蔚敏版数据结构。
代码如下:
PS:遍历我就没写了,深度优先,广度优先,前面都写过了,偷懒了!
#include"stdafx.h" #include"Basic_Symbol.h" #include"ZJC_Queue.h" //数据结构学习记录..ZJC //vex:顶点,arc:边 //还是自己动手好啊,写多了理解就会加深啊! #define MAX_VERTEX_NUM 20 //单条链表的最大数量 typedef int InfoType; typedef int VertexType ; //最低级 typedef struct ArcNode //链表中的元素数据结构,即表节点 { int adjvex; //该弧所指向的顶点位置 struct ArcNode *next; //指向下一条弧的指针 InfoType *info; //该数据域存储和边或者弧相关的信息,如权值等其他信息。 }ArcNode; //二级控制 typedef struct VNode { VertexType data; //存储顶点的名或其他信息的数据域 ArcNode *firstarc; //指向链表中的第一个节点 }VNode,AdjList[MAX_VERTEX_NUM]; //一级控制 typedef struct { AdjList vertices; int vexnum,arcnum; //这个图中的顶点数量,边数量 int kind; //图的种类标志 }ALGraph; //相关定义完毕!下面是函数实现 //下面是:有向图的邻接链表存储方式构建 Status CreatALGraph(ALGraph *G) { int ListNum = 0; //保证表从0开始,然后依次累加,这样不会离散.. int vex,arc; int tempVex; int tempVexNum; //临时数,存储总的指向的节点数量 ArcNode* node = NULL; ArcNode* tempPoint = NULL; printf("请输入要建立的图的顶点数,边数:\n"); scanf("%d %d",&vex,&arc); //3,3 G->vexnum = vex; //3 G->arcnum = arc; //3 //开始构建顶点关系,依次询问每个顶点指向了其他的哪些顶点,循环次数为总的顶点数,只关心箭头从谁发出 //初始化: for(int i = 0;i<MAX_VERTEX_NUM;i++) G->vertices[i].data = -1; for(int i = 0;i<vex;i++) { printf("请问%d号节点指向了多少个节点?请输入:\n",i+1); scanf("%d",&tempVexNum); if(tempVexNum > 0) //存在指向,才执行下面 ,如果是无向图,那么就不存在这个,因为没有孤岛 { // printf("\nlistNum = %d",ListNum); G->vertices[ListNum].data = i; //这个data用来存储头结点的号数 if(ListNum >= MAX_VERTEX_NUM ) { printf("满了"); return 0; } for(int j = 0;j<tempVexNum;j++) //每输入就挂在链表上 { printf("\n请分别所指向的节点%d的编号:\n",j+1); scanf("%d",&tempVex); node = (ArcNode*)malloc(sizeof(ArcNode)); //创建链表节点, node->next = NULL; node->adjvex = tempVex; // 先暂时写着吧,也就是说我现在把这个理解成了被指向的顶点的编号 if(j == 0) //表示是第一个,才头结点连接,否则用表节点连接 { G->vertices[i].firstarc = node; //连接成功 } else { // printf("\n检测上一个的指针是否正确:%d",tempPoint->adjvex); tempPoint->next = node; //连接在上一个的末尾 } // printf("节点创建成功!其号数:%d",node->adjvex); tempPoint = node; //tempPoint是上一个节点的地址。 } printf("\nA节点%d的链表建立完成!!!开始下一个节点的链表建立\n",i); } else { G->vertices[ListNum].data = -1; G->vertices[i].firstarc = NULL; } ListNum++; //创建,全局静态,刚刚的问题就是如果输入的vex = 0.那么就不会记录进去..无论是否为0,都应该被记录 //OK,这样就知道了节点i所指向的其他全部节点的编号了 } printf("\n邻接表建立完成!"); return 1; } void ShowGraph(ALGraph G) //验证邻接表的创建是否正确,主要是验证其中的数据.. { // printf("\n检测数据..G.arcnum = %d,G.vexnum = %d,G[0].data = %d",G.arcnum,G.vexnum,G.vertices[0].data); ArcNode* temp; for(int i = 0;i<G.arcnum ;i++) //对每一条链表进行验证,检测次数为所有边的条数 { printf("\n输出链表%d号中的所有数据如下:",i + 1); if(G.vertices[i].data != -1) //表明有数据 { //输出该条链表中的所有数据 temp = G.vertices[i].firstarc; while(temp) { printf("%d , ",temp->adjvex); temp = temp->next; } } else { printf(" %d号链表为空!",i); } } }
运行结果: