图的邻接表表示法的实现

 
 

邻接表(Adjacency List)是图的一种顺序存储与链式存储结合的存储方法。邻接表表示法类似于树的孩子链表表示法。就是对于图G 中的每个顶点vi,将所有邻接于vi 的顶点vj 链成一个单链表,这个单链表就称为顶点vi 的邻接表,再将所有点的邻接表表头放到数组中,就构成了图的邻接表。在邻接表表示中有两种结点结构,如图8.9 所示。

图的邻接表表示法的实现_第1张图片
一种是顶点表的结点结构,它由顶点域(vertex)和指向第一条邻接边的指针域(firstedge)构成,另一种是边表(即邻接表)结点,它由邻接点域(adjvex)和指向下一条邻接边的指针域(next)构成。对于网图的边表需再增设一个存储边上信息(如权值等)的域(info),网图的边表结构如图8.10 所示。
图的邻接表表示法的实现_第2张图片

#include <stdio.h>
#include <stdlib.h>

#define MaxVertexNum 50

typedef struct node *EdgeNode;
typedef struct vnode *VertexNode;
typedef struct graph *ALGraph;

struct node
{						//边表节点
	int adjvex;			//邻接点域
	EdgeNode next;		//链域
};

struct vnode
{						//顶点表节点
	int vertex;			//顶点域
	EdgeNode firstedge; //边表头指针
};

struct graph
{
	struct vnode *adjlist;
	int n;				//图中当前顶点数
	int e;				//图中当前边数
};

void CreatALGraph(ALGraph G)
{
	int i, j, k;
	int a;
	EdgeNode s;			//定义边表节点
	printf("请输入顶点数和边数:\n");
	scanf("%d %d", &i, &j);
	G->n = i;
	G->e = j;
	printf("请输入顶点编号:\n");
	for (i = 1; i <= G->n; i++)		//建立顶点表
	{
		scanf("%d", &a);
		G->adjlist[i].vertex = a;	//读入顶点信息
		G->adjlist[i].firstedge = NULL;	//边表头指针置为空
	}
	
	printf("请输入由两个定点构成的边,示例:0 1\n");
	for (k = 0; k < G->e; k++)
	{
		scanf("%d %d", &i, &j);		//读入边(Vi, Vj)的顶点对应的序号
		s = malloc(sizeof(struct node));	//生成边表节点
		s->adjvex = j;
		s->next = G->adjlist[i].firstedge;
		G->adjlist[i].firstedge = s;	//将新节点*s插入顶点Vi的边表头部
		/*若建立为无向图,则添加下面的代码*/
		/*
		s = malloc(sizeof(struct node));
		s->adjvex = i;
		s->next = G->adjlist[j].firstedge;
		G->adjlist[j].firstedge = s;
		*/
	}
}


int main()
{
	int i, j;
	ALGraph G = malloc(sizeof(struct graph));
	G->adjlist = (struct vnode *)malloc(sizeof(struct vnode) * MaxVertexNum);
	CreatALGraph(G);

	for (i = 1; i <= G->n; i++)
	{
		while (G->adjlist[i].firstedge)
		{
			printf("%d -> ", G->adjlist[i].vertex);
			printf("%d\n", G->adjlist[i].firstedge->adjvex);
			G->adjlist[i].firstedge = G->adjlist[i].firstedge->next;
		}
	}
	
	return 0;
}

图的邻接表表示法的实现_第3张图片


你可能感兴趣的:(图的邻接表表示法的实现)