对于无向图(图2)的存储,最常用的存储方式就是邻接表。那么什么是邻接表呢?
如图2,它是通过数组和链表的结合。
图的顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易地读取顶点信息,更加方便。图中每个顶点Vi的所有邻接点构成一个线性表,由于邻接点的个数不确定,所以我们选择用单链表来存储。这样一个邻接表就生成了。
举个具体的例子:如图2中v0顶点,相连有三条边(v1,v0)(v2,v0),(v3,v0)。最后v0first指针依次指向就是1,2,3。
图1 邻接表
图2 无向图
具体代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10000
#define MED_SIZE 100
typedef struct Node{
char quan;//如果边有权重就定义权重
int value;//邻接点的值
struct Node *next;
}node;
typedef struct Tablenode{//定义邻接表的一个结点
char data[MED_SIZE];
int val;
node *first;
}tablenode,Tblearray[MAX_SIZE];//定义一个邻接表结构体数组
typedef struct Graphic{//定义一个邻接表
Tblearray a;//指向邻接表结构体首节点
int numous, number;//定义邻接表的边数,顶点数
}Graph;
void Creategragh(Graph *Gra)//新建邻接表函数
{
int numous = 0, number = 0,i=0,k=0,j=0,quan=0;
node *newnode = NULL;
printf("请输入你要建立的边数,顶点数\n");
scanf_s("%d,%d", &numous, &number);
for (i=0;i< number;i++)
{
scanf_s("%s", Gra->a[i].data,sizeof(Gra->a[i].data));//输入邻接表节点的Vi名称
Gra->a[i].val = i;//邻接表下标
Gra->a[i].first = NULL;//初始化每个节点的first指针
}
for (i=0;i< numous;i++)
{
printf("请输入要建立的边(vk,vj)下标\n");
scanf_s("%d,%d",&k,&j);
printf("边的权\n");
scanf_s("%d", &quan);
newnode = (node *)malloc(sizeof(node));
newnode->value = k;
newnode->quan = quan;
newnode->next = Gra->a[j].first;//采用的是头插法
Gra->a[j].first = newnode;
newnode = (node *)malloc(sizeof(node));
newnode->value = j;
newnode->quan = quan;
newnode->next = Gra->a[k].first;
Gra->a[k].first = newnode;
}
}
int main(void)
{
Graph *Gra=(Graph *)malloc(sizeof(Graph));
Creategragh(Gra);
}