图的邻接多重表存储

本文介绍了一种使用多重链表实现图结构的方法,并提供了完整的C语言代码示例。通过定义弧节点和顶点节点,文章实现了图的创建、插入、删除等基本操作,并展示了如何遍历和打印图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include "stdio.h"

#define MAX_VEX_NUM 20

enum E_VisitIf
{
	unisited = 0,
	visited=1,
};

//弧节点
struct ArcNode 
{
	E_VisitIf mark;
	int iIndex, jIndex;//顶点i,j在图中的位置
	ArcNode *iNext;//与i顶点相关的下一个弧
	ArcNode *jNext;//与j顶点相关的下一个弧
};

struct VNode 
{
	char vexName;
	ArcNode *head;//头结点
};

struct AMLGraph 
{
	VNode AdjMuList[MAX_VEX_NUM];//顶点数组
	int vexNum, arcNum;
};

//生成一个弧节点并初始化,返回头节点
ArcNode *getHeadNode()
{
	ArcNode *pNode = (ArcNode *)malloc(sizeof(ArcNode));
	if (pNode)
	{
		pNode->iIndex = pNode->jIndex = -1;
		pNode->iNext = pNode->jNext = NULL;
		pNode->mark = unisited;
	}

	return pNode;
}

ArcNode *getArcNode(int iIndex, int jIndex)
{
	ArcNode *pNode = getHeadNode();
	if (pNode)
	{
		pNode->iIndex = iIndex;
		pNode->jIndex = jIndex;
	}

	return pNode;
}

//定位顶点的下标
int vexLocation(AMLGraph g, char vex)
{
	for (int i=0;i<g.vexNum;i++)
	{
		if (g.AdjMuList[i].vexName==vex)
		{
			return i;
		}
	}

	return -1;
}

//创建图
void createGraph(AMLGraph *G)
{
	printf("输入图的顶点数和边数\n");
	scanf("%d%d", &G->vexNum, &G->arcNum);
	char ch;
	ch = getchar();

	printf("请输入顶点集\n");
	for (int i=0;i<G->vexNum;i++)
	{
		char name;
		scanf("%c", &name);
		ch = getchar();
		G->AdjMuList[i].vexName = name;
		G->AdjMuList[i].head = getHeadNode();//建立头结点,并让头指针指向头节点
	}

	fflush(stdin);//刷新缓冲区,把缓冲区里的东西丢掉

	printf("请输入顶点的关系\n");

	for (int i=0;i<G->arcNum;i++)
	{
		char vex1, vex2;
		scanf("%c%c", &vex1, &vex2);
		ch = getchar();
		int location1 = vexLocation(*G, vex1);
		int location2 = vexLocation(*G, vex2);

		ArcNode *pNode = getArcNode(location1, location2);
		pNode->iNext = G->AdjMuList[location1].head->iNext;
		G->AdjMuList[location1].head->iNext = pNode;
		pNode->jNext = G->AdjMuList[location2].head->iNext;
		G->AdjMuList[location2].head->iNext = pNode;
	}
}

void destoryGraph(AMLGraph *G)
{
	for (int i=0;i<G->vexNum;i++)
	{
		ArcNode *next = G->AdjMuList[i].head->iNext;
		while (next!=NULL)
		{
			ArcNode *freeNode = next;
			next = next->iIndex == i ? next->iNext : next->jNext;
			if (freeNode->iIndex==i)
			{
				free(freeNode);
			}

		}
		free(G->AdjMuList[i].head);
		G->AdjMuList[i].head = NULL;
		G->AdjMuList[i].vexName = ' ';
		G->vexNum = G->arcNum = 0;
	}
}

//顶点vex1与vex2是否相连接
bool graphIsAdj(AMLGraph g, char vex1, char vex2)
{
	int location = vexLocation(g, vex1);
	ArcNode *next = g.AdjMuList[location].head->iNext;
	while (next!=NULL)
	{
		if (g.AdjMuList[next->iIndex].vexName==vex2  || g.AdjMuList[next->iIndex].vexName==vex2)
		{
			return true;
		}
		next = next->iIndex == location ? next->iNext : next->jNext;
	}
	return false;
}

//插入边(弧)
void insertArc(AMLGraph *G, char vex1, char vex2)
{
	int location1 = vexLocation(*G,vex1);
	int location2 = vexLocation(*G,vex2);
	ArcNode *node = getArcNode(location1, location2);
	node->iNext = G->AdjMuList[location1].head->iNext;
	G->AdjMuList[location1].head->iNext = node;
	node->jNext = G->AdjMuList[location2].head->jNext;
	G->AdjMuList[location2].head->iNext = node;
	G->arcNum++;
}

//删除边(弧)
void deleteArc(AMLGraph *G, char vex1, char vex2)
{
	G->arcNum--;
	int location1 = vexLocation(*G, vex1);
	int location2 = vexLocation(*G, vex2);
	ArcNode *next = G->AdjMuList[location1].head->iNext;
	ArcNode *pre = G->AdjMuList[location2].head;
	while (next!=NULL)
	{
		if (next->iIndex==location2)
		{
			if (pre==G->AdjMuList[location1].head || pre->iIndex==location1)
			{
				pre->iNext = next->jNext;
			}
			else
			{
				pre->jNext = next->jNext;
			}
			break;
		}
		else if (next->jIndex==location2)
		{
			if (pre==G->AdjMuList[location1].head || pre->iIndex==location1)
			{
				pre->iNext = next->iNext;
			}
			else
			{
				pre->jNext = next->iNext;
			}
			break;
		}

		pre = next;
		next = next->iIndex == location1 ? next->iNext : next->jNext;
	}

	next = G->AdjMuList[location2].head->iNext;
	pre = G->AdjMuList[location2].head;

	while (next!=NULL)
	{
		if (next->iIndex==location1)
		{
			if (pre==G->AdjMuList[location2].head || pre->iIndex==location2)
			{
				pre->iNext = next->jNext;
			}
			else
			{
				pre->jNext = next->jNext;
			}
			free(next);
			break;
		}
		else if (next->jIndex==location1)
		{
			if (pre==G->AdjMuList[location2].head || pre->iIndex==location2)
			{
				pre->iNext = next->iNext;
			}
			else
			{
				pre->jNext = next->iNext;
			}
			free(next);
			break;
		}

		pre = next;
		next = next->iIndex == location2 ? next->iNext : next->jNext;
	}
}

//打印图的多重链表
void printGraph(AMLGraph g)
{
	for (int i=0;i<g.vexNum;i++)
	{
		printf("%c的邻接点有: ", g.AdjMuList[i].vexName);
		ArcNode *next = g.AdjMuList[i].head->iNext;
		while (next!=NULL)
		{
			int index = next->iIndex == i ? next->jIndex : next->iIndex;
			printf("%c", g.AdjMuList[index].vexName);
			next = next->iIndex == i ? next->iNext : next->jNext;
		}

		printf("\n");
	}
}

int main(void)
{
	AMLGraph G;
	createGraph(&G);
	printGraph(G);

	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值