有向图的十字链表表示法

有向图的十字链表表示法

在这里插入图片描述
在这里插入图片描述
代码实现:

#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define MAXNum 100
//定义无穷大
#define  MAXInt 32767
typedef int Status;
//定义顶点数据类型
typedef char VerTexType;
//定义节点权重的类型
typedef int OtherInfo;
//定义弧结点的类型
typedef struct ArcNode{
	int startvex;
	ArcNode* start;
	int endvex;
	ArcNode* end;
	OtherInfo info;
}ArcNode;
//定义表结点的数据类型
typedef struct VNode {
	VerTexType data;
	ArcNode* firstin;//以data结点为尾的弧,即other→data
	ArcNode* firstout;//以data结点为头的弧,即data→other
}VNode,AdjList[MAXNum];
//定义图的数据类型
typedef struct {
	AdjList vertices;//十字链表
	int vexnum, arcnum;//图的结点总个数以及总边数
}ALGraph;
//查找结点数据x在邻接表中处于什么位置
int Locate(ALGraph G, VerTexType x) {
	for (int i = 0; i < G.vexnum; i++) {
		if (G.vertices[i].data == x) {
			return i;
		}
	}
	return -1;
}
Status createTenList(ALGraph& G) {
	cout << "请输入图的总结点数和总弧数:" << "\n";
	cin >> G.vexnum >> G.arcnum;
	cout << "请依次输入每个结点:" << "\n";
	for (int i = 0; i < G.vexnum; i++) {
		cin >> G.vertices[i].data;
		G.vertices[i].firstin = NULL;
		G.vertices[i].firstout = NULL;
	}
	cout << "请依次输入每条弧的起点以及终点:" << "\n";
	for (int i = 0; i < G.arcnum; i++)
	{
		VerTexType x, y;
		cin >> x >> y;
		//查找结点x,y在顶点表中的下标
		int xIndex=Locate(G, x);
		int yIndex=Locate(G, y);
		if (xIndex==-1||yIndex==-1)
		{
			return -1;
		}
		else {
			//创建结点,startvex是xIndex,endvex是yIndex的结点
			ArcNode* newNode = new ArcNode;
			newNode->startvex = xIndex;
			newNode->endvex = yIndex;
			newNode->info = 1;
			//将该结点添加到以xIndex为起始结点的链表上
			newNode->start = G.vertices[xIndex].firstin;
			G.vertices[xIndex].firstin = newNode;
			//将该结点添加到以yIndex为尾结点的链表上
			newNode->end = G.vertices[yIndex].firstout;
			G.vertices[yIndex].firstout = newNode;
		}
	}
	return OK;
}
void outPut(ALGraph G) {
	cout << "输出顶点表如下\n" << "";
	for (int i = 0; i < G.vexnum; i++)
	{
		cout << G.vertices[i].data << " ";
	}
	for (int i = 0; i < G.vexnum; i++)
	{
		ArcNode* pFirst=G.vertices[i].firstin;//获取i结点入度表的第一条边
		ArcNode* pLast=G.vertices[i].firstout;//获取i结点入度表的第一条边
		printf("\n以%c结点为起点的边为:\n",G.vertices[i].data);
		while (pFirst)
		{
			printf(" 边:%c %c", G.vertices[pFirst->startvex].data, G.vertices[pFirst->endvex].data);
			pFirst = pFirst->start;
		}
		printf("\n以%c结点为起终点的边为:\n", G.vertices[i].data);
		while (pLast)
		{
			printf(" 边:%c %c", G.vertices[pLast->startvex].data, G.vertices[pLast->endvex].data);
			pLast = pLast->end;
		}
	}
}
//求某个点的出度
int outDegree(ALGraph G, VerTexType x) {
	int outDegree = 0;
	for (int i = 0; i < G.vexnum; i++)
	{
		if (G.vertices[i].data==x)
		{
			ArcNode* p = G.vertices[i].firstin;
			while (p)
			{
				outDegree++;
				p = p->start;
			}
			break;
		}
	}
	return outDegree;
}

//求某个点的入度
int InDegree(ALGraph G, VerTexType x) {
	int inDegree = 0;
	for (int i = 0; i < G.vexnum; i++)
	{
		if (G.vertices[i].data == x)
		{
			ArcNode* p = G.vertices[i].firstout;
			while (p)
			{
				inDegree++;
				p = p->end;
			}
			break;
		}
	}
	return inDegree;
}
int main() {
	ALGraph G;
	createTenList(G);
	outPut(G);
	VerTexType x;
	cout << "\n请输入需要求出度和入度的结点:" << "\n";
	cin >> x;
	int out = outDegree(G, x);
	printf("\n该结点的出度为:%d\n", out);
	int in = InDegree(G, x);
	printf("\n该结点的入度为:%d\n", in);
	return 0;
}

测试样例:
输入的测试样例为上述的有向图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

菜菜iwi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值