邻接表存储图(无向图为例)

本文详细介绍了一种图数据结构的实现方式——邻接表,包括其基本操作、代码实现及测试过程。通过邻接表可以高效地存储图的顶点和边信息,适用于无向图的场景。文章提供了完整的C语言代码示例,涵盖了图的创建、遍历、查找顶点度数及判断边的存在性等功能。

一、图的样式

二、实现代码

/*
项目名称:邻接表存储图
编译环境:VC++ 2008
作者相关:。。。
最后修改:2019.10.28
学习目标:1.掌握邻接表存储图的基本操作
注意事项:1.测试所有功能是否正常

遇到问题:

1.创建单链表时用的的是LinkList *类型,LinkList本身是结构体指针类型,
在创建时的形参相当于一个二级指针;
2.当函数形参为Node *类型时,Node是结构体类型
问题就是链表的创建使用Node*不就相当于LinkList?若将形参改为LinkList L,能否建立链表?
感觉应该是:Node * = LinkList &L = LinkList *L
*/
#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTEX_NUM 20
#define OK      1
#define ERROR   0

typedef char InfoType;
typedef char VertexType;
typedef bool Status;

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 vexs;
	int vexnum,arcnum;//顶点数和弧数
	int kind;//图的种类标志

}ALGraph;

Status CreateGraph(ALGraph &G);

Status CreateUDG(ALGraph &G);

Status CreateLinkList(ArcNode *N);

void ShowLinkList(ArcNode *N);

int VexDu(ALGraph G,VertexType v);

int GetIndex(ALGraph G,VertexType v);

Status ArcExist(ALGraph G,VertexType v1,VertexType v2);

void AllAdjDot(ALGraph G,VertexType v1);

int main()
{
	ALGraph G;
	VertexType v,v1,v2;

	CreateGraph(G);

	printf("请输入要求度数的顶点:\n");
	fflush(stdin);
	scanf("%c",&v);
	int du=VexDu(G,v);
	printf("顶点%c的度为%d\n\n",v,du); 

	printf("请输入要判断是否存在边的两个顶点:\n");
	fflush(stdin);
	scanf("%c,%c",&v1,&v2);
	ArcExist(G,v1,v2);

	AllAdjDot(G,v);

	return 0;
}

Status CreateGraph(ALGraph &G)
{
	printf("请输入要构造的图的种类"
		"[UDG(3)]\n");
	scanf("%d",&G.kind);
	switch(G.kind)
	{
		/*case 0: return CreateDG(G);
		case 1: return CreateDN(G);
		case 2:return CreateUDN(G);*/
	case 3:return CreateUDG(G);

	default :return ERROR;
	}
	return OK;
}

Status CreateUDG(ALGraph &G)
{
	int IncInfo,i,j,index,w;
	VertexType v1,v2;
	ArcNode N;

	printf("请输入无向图的顶点数和边数:\n");
	scanf("%d%d",&G.vexnum,&G.arcnum);
	printf("\n");
	for(i=0;i<G.vexnum;i++)//构造顶点数组
	{
		printf("请输入第%d个顶点\n",i+1);
		fflush(stdin);
		scanf("%c",&G.vexs[i].data);
		G.vexs[i].firstarc=NULL;
	}
	printf("\n");
	for(j=0;j<G.vexnum;j++)
	{
		printf("请输入顶点%c含有邻接点的个数\n",G.vexs[j].data);
		CreateLinkList(&N);
		G.vexs[j].firstarc=N.next;//N是头结点,啥也不含
		printf("\n");
	}

	return OK;
}
//创建无头结点的单链表来表示边表
Status CreateLinkList(ArcNode *N)//尾插法原理
{
	int i,NodeNum,index;

	ArcNode *p=N,*s;

	fflush(stdin);
	scanf("%d",&NodeNum);
	for(i=0;i<NodeNum;i++)
	{
		printf("请输入链表的第%d个结点储存的顶点下标值\n",i+1);
		fflush(stdin);
		scanf("%d",&index);
		s=(ArcNode *)malloc(sizeof(ArcNode));
		s->adjvex=index;
		p->next=s;
		p=s;
	}
	p->next=NULL;

	return OK;
}
//验证链表是否创建成功
void ShowLinkList(ArcNode *N)
{
	ArcNode *p=N->next;
	while(p)
	{
		printf("%d ",p->adjvex);
		p=p->next;
	}
}
//返回vex中顶点v的度
int VexDu(ALGraph G,VertexType v)
{
	int index=GetIndex(G,v);

	ArcNode *p=G.vexs[index].firstarc;
	int i=0;

	while(p)
	{
		++i;
		p=p->next;
	}

	return i;
}
//获得顶点v在G中的下标
int GetIndex(ALGraph G,VertexType v)
{
	int i;
	for(i=0;i<G.vexnum;i++)
		if(G.vexs[i].data==v)
			return i;
	if(i==G.vexnum)
		return -1;
}

//判断顶点v1,v2是否存在边
Status ArcExist(ALGraph G,VertexType v1,VertexType v2)
{
	int index1,index2;

	index1=GetIndex(G,v1);
	index2=GetIndex(G,v2);

	ArcNode *p=G.vexs[index1].firstarc;

	while(p)
	{
		if(p->adjvex==index2)
		{
			printf("顶点%c和%c存在边\n\n",v1,v2);
			return OK;
		}
		else
			p=p->next;
	}

	return ERROR;
}
//求某个顶点的所有邻接点
void AllAdjDot(ALGraph G,VertexType v1)
{
	int index=GetIndex(G,v1);
	ArcNode *p=G.vexs[index].firstarc;
	printf("顶点%c的所有邻接点为",v1);
	while(p)
	{
		printf("%c ",G.vexs[p->adjvex].data);
		p=p->next;
	}
	printf("\n\n");
}

 

三、输出结果

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值