邻接表=邻接链表。
我觉得,还是要自己写写,写出来,理解才会更深一点,以前眼高手低,不知其中厉害啊。
其实还是蛮有趣的!我觉得,还是要把数据结构学好,工具总是在变,但是思想才是最重要的。
代码的注释应该还是非常详细的,学这个,还是要结合书上的图,就是严蔚敏版数据结构。
代码如下:
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);
}
}
}
图如下:
运行结果: