(一)邻接表图文解析

邻接表的结构比较复杂,包括顶点的存储结构和边的存储结构;
顶点结点包括数据域和指针域,边结点包括数据域、指针域和边结点所指向的顶点位置;
其中顶点结点由<mark>一维数组</mark>储存,每个顶点结点又以链栈的结构连接着边结点;


图的形式与邻接表的形式:

(二)邻接表代码解析

2.1 邻接表的存储结构

typedef struct	EdgeNode	//边结点
{
	int adjvex;				//邻接点
	OtherInfo info;			//数据域,边的权值
	struct EdgeNode *next;	//指针域,指向下一条边 
}EdgeNode;

typedef struct				//顶点结点
{
	VerTexType data;		//数据域,顶点结点的数据
	EdgeNode *firstedge;	//指针域,指向对应的边
}VextexNode,AdjList[MAXVEX];

typedef struct			
{
	AdjList adjList;		//存放顶点结点的数组
	int numNodes,numEdges;	//顶点数和边数
}ALGraph;

2.2 邻接表的创建

void  CreateALGraph(ALGraph &G)
{
	int i,j,k;
	OtherInfo w;
	printf("请输入顶点数和边数:");
	scanf("%d %d",&G.numNodes,&G.numEdges);

	for(i=0;i<G.numNodes;i++)//顶点结点
	{
		fflush(stdin);
		printf("请输入第%d个顶点数据:",i+1);
		scanf("%c",&G.adjList[i].data);//输入顶点结点数据
		G.adjList[i].firstedge=NULL;//初始化边结点的指针为空
	}
	
	for(k=0;k<G.numEdges;k++)//边结点
	{
		printf("请输入边(vi,vj)上的顶点序号及权值:");
		scanf("%d %d %d",&i,&j,&w);
		EdgeNode *p1,*p2;//创建两个新的边结点

		p1=(EdgeNode *)malloc(sizeof(EdgeNode));//为边结点分配空间
		p1->adjvex=j;				//新边结点所指向顶点的数组位置
		p1->next=G.adjList[i-1].firstedge;	//新边结点p1插入顶点结点后
		G.adjList[i-1].firstedge=p1;		//新边结点p1插入顶点结点后
		p1->info=w;//边结点的权值
		
		//因为为无向图,所以同时需要在相应顶点上接入相同权值的边结点
		p2=(EdgeNode *)malloc(sizeof(EdgeNode));
		p2->adjvex=i;
		p2->next=G.adjList[j-1].firstedge;
		G.adjList[j-1].firstedge=p2;
		p2->info=w;
	}
}

2.3 邻接表的遍历

void TravelALGraph(ALGraph G)
{
	int i;
	EdgeNode *p;
	for(i=0;i<G.numNodes;i++)
	{
		p=G.adjList[i].firstedge;
		while(p)
		{
			printf("第%d个顶点(边的权值:%d)-->第%d个顶点\n",i+1,p->info,p->adjvex);
			p=p->next;		
		}
		if(!p)
			printf("\n");
	}
}

2.4 邻接表的查找

void LocateALGraph(ALGraph G)
{
	int i,j;
	EdgeNode *p;
	printf("请输入顶点序号:");
	scanf("%d",&i);
	printf("该顶点信息为:%c\n",G.adjList[i-1].data);

	printf("请输入需要查找的边的两个顶点:");
	scanf("%d %d",&i,&j);
	p=G.adjList[i-1].firstedge;//从位置为i-1的顶点出发
	while(p)//遍历该顶点的所有边
	{
		if(p->adjvex==j)//查找到连接着顶点位置为j的边
		{
			printf("该边的权值为:%d\n",p->info);
			break;
		}
		else
			p=p->next;
	}
}

(三)源代码及测试

3.1 源代码

#include<stdio.h>
#include<malloc.h>

#define MAXVEX 100 

typedef int OtherInfo;	
typedef char VerTexType;	

typedef struct	EdgeNode	
{
	int adjvex;			
	OtherInfo info;			
	struct EdgeNode *next;	
}EdgeNode;

typedef struct			
{
	VerTexType data;		
	EdgeNode *firstedge;	
}VextexNode,AdjList[MAXVEX];

typedef struct			
{
	AdjList adjList;		
	int numNodes,numEdges;
}ALGraph;

void  CreateALGraph(ALGraph &G)
{
	int i,j,k;

	OtherInfo w;

	printf("请输入顶点数和边数:");
	scanf("%d %d",&G.numNodes,&G.numEdges);

	for(i=0;i<G.numNodes;i++)
	{
		fflush(stdin);
		printf("请输入第%d个顶点数据:",i+1);
		scanf("%c",&G.adjList[i].data);
		G.adjList[i].firstedge=NULL;
	}
	
	for(k=0;k<G.numEdges;k++)
	{
		printf("请输入边(vi,vj)上的顶点序号及权值:");
		scanf("%d %d %d",&i,&j,&w);
		EdgeNode *p1,*p2;

		p1=(EdgeNode *)malloc(sizeof(EdgeNode));
		p1->adjvex=j;				
		p1->next=G.adjList[i-1].firstedge;
		G.adjList[i-1].firstedge=p1;
		p1->info=w;

		p2=(EdgeNode *)malloc(sizeof(EdgeNode));
		p2->adjvex=i;
		p2->next=G.adjList[j-1].firstedge;
		G.adjList[j-1].firstedge=p2;
		p2->info=w;
	}
}
void TravelALGraph(ALGraph G)
{
	int i;
	EdgeNode *p;
	for(i=0;i<G.numNodes;i++)
	{
		p=G.adjList[i].firstedge;
		while(p)
		{
			printf("第%d个顶点(边的权值:%d)-->第%d个顶点\n",i+1,p->info,p->adjvex);
			p=p->next;		
		}
		if(!p)
			printf("\n");
	}
}
void LocateALGraph(ALGraph G)
{
	int i,j;
	EdgeNode *p;
	printf("请输入顶点序号:");
	scanf("%d",&i);
	printf("该顶点信息为:%c\n",G.adjList[i-1].data);

	printf("请输入需要查找的边的两个顶点:");
	scanf("%d %d",&i,&j);
	p=G.adjList[i-1].firstedge;//从位置为i-1的顶点出发
	while(p)//遍历该顶点的所有边
	{
		if(p->adjvex==j)//查找到连接着顶点位置为j的边
		{
			printf("该边的权值为:%d\n",p->info);
			break;
		}
		else
			p=p->next;
	}
}
int main()
{
	ALGraph G;	
	CreateALGraph(G);
	TravelALGraph(G);
	LocateALGraph(G);
	return 0;
}

3.2 测试结果

测试环境 : Windows 10
编译软件 : Visual C++ 6.0