图--邻接表

邻接表是图结构中的一种存储结构,适用于存储无向图和有向图。

邻接表存储图的实现方式是,给图中的各个顶点独自建立一个链表,用节点存储该顶点,用链表中其他节点存储各自的临界点。

与此同时,为了便于管理这些链表,通常会将所有链表的头节点存储到数组中(也可以用链表存储)。也正因为各个链表的头节点存储的是各个顶点,因此各链表在存储临界点数据时,仅需存储该邻接顶点位于数组中的位置下标即可。

 将图画出来,在编写代码思路会比较清晰

从图中我们知道,顶点表的各个结点由data和firstedge两个域表示,data是数据域,存储顶点的信息。

firstedge是指针域,指向边表的第一个结点,即此顶点的第一个邻接点。

边表结点由adjvex和next两个域组成。adjvex是邻接点域,存储某顶点的邻接点在顶点表中的下标,next则存储指

向边表中下一个结点的指针,比如v1顶点与v0、v2互为邻接点,则在v1的边表中,adjvex分别为v0的0和v2的2.

如果想知道某个顶点的度,就去查找这个顶点的边表中结点的个数。

若要判断顶点vi和vj是否存在边,只需要测试顶点vi的边表adjvex中是否存在结点vj的下标就行了。

若求顶点的所有邻接点,其实就是对此顶点的边表进行遍历,得到的adjvex域对应的顶点就是邻接点。
 

代码如下:

#include "stdio.h"
#include "stdlib.h"

#define Maxvew 100		//顶点数量最大值 

typedef struct Edgenode		//邻接结点 
{
	int adjvex;				//邻接结点存储的数组下标 
	int weight;				//用于存储权值,对于非网图可以不需要
	struct Edgenode *next;	//链域,指向下一个邻接点
}Edgenode;

typedef struct Vertexnode	//顶点 表节点 
{
	char data;				//顶点域,存储顶点信息
	Edgenode *firstedge;	//边表头指针
}Vertexnode,AdjList[Maxvew];

typedef struct				// 数组、顶点、边 结构体 
{
	AdjList adjList;		//顶点数组 
	int numVertexes,numEdges;//图中当前顶点数和边数
}GrapAdList;

void CreateALGraph(GrapAdList *G)   //创建邻接图表 
{
	int i,j,k;
	Edgenode *e;		//创建邻接结点 
	printf("输入顶点数和边数:\n");
	scanf("%d,%d",&G->numVertexes,&G->numEdges);//输入顶点数和边的数量 
	for(i=0;i<G->numVertexes;i++)		//for循环  顶点的数量 
	{
		scanf(&G->adjList[i].data);		//输入顶点存储的数据data 
		G->adjList[i].firstedge = NULL;	//设置顶点的邻接结点先为空 
	}
	for(k=0;k<G->numEdges;k++)		//for循环 边的数量 
	{
		printf("输入边(vi,vj)上的顶点序号:\n");
		scanf("%d,%d",&i,&j);			//输入边的弧头和弧尾 
		e = (Edgenode *)malloc(sizeof(Edgenode)); //给邻接结点分配内存 
		e->adjvex=j;						//将数字j  代入邻接点的数据域里 
		e->next=G->adjList[i].firstedge;	//邻接点的next 指向NULL  (链表操作) 
		G->adjList[i].firstedge=e;			//顶点的firstedge[i]指针指向该邻接结点 
		
		e=(Edgenode *)malloc(sizeof(Edgenode));	 //再次分配出个邻接结点 
		e->adjvex=i;			//将i的值代入邻接结点的数据域 
		e->next=G->adjList[j].firstedge;  //邻接点的next 指向NULL  (链表操作)
		G->adjList[j].firstedge=e;		//邻接点接在顶点结点adjList[j]后 
	}
}

void digui(Edgenode *k)  //使用递归  打印邻接表的后续数据 
{
	if(k==NULL)			//如果邻接表的第二链为空 则输出换行  停止递归 
	{
		printf("\n");
	}
	else				//否则 
	{
		printf("%d->\t",k->adjvex);		//打印出后续数据 
		k=k->next;					//递归操作   替换参数  循环递归 
		return digui(k);			
	}	
}

void printfGraph(GrapAdList *G)
{
	int i;
	for(i=0;i<G->numVertexes;i++)	//for循环顶点的个数 
	{
		printf("%d\t",i);				//打印出顶点数组下标 
		if(G->adjList[i].firstedge==NULL)		//如果邻接点为空 则换行 
		{	
			printf("\n");
			
		}
		else{
			printf("%d->\t",G->adjList[i].firstedge->adjvex);	//否则输出后续邻接结点 数据 
			Edgenode *k=G->adjList[i].firstedge->next;			//递归操作  创建邻接结点k指针指向目前递归到的指针节点的next 
			digui(k);			//递归 
		}
		
	}
}

int main()
{
	GrapAdList G;			//数据 结构体 
	CreateALGraph(&G);		//创建邻接表 
	printfGraph(&G);		//输出邻接表 
	return 0;
} 

编译结果:

 代码有些许漏洞,待后续改进。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wiyoo0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值