图的存储结构——十字链表法

图的存储结构——十字链表法

(1)定义结构体

#define MaxVertexNum 30
typedef int VexLocalType;	//结点位序
typedef char VertexType;	//结点类型
typedef int WeighType;		//权值类型

typedef struct ArcNode {

	VexLocalType tailVex;	//尾结点
	VexLocalType headVex;	//头结点
	struct ArcNode* hLink;	//弧头相同的下一条弧
	struct ArcNode* tLink;	//弧尾相同的下一条弧
	WeighType info;			//权值

}ArcNode;

typedef struct VerNode {

	VertexType data;		//结点元素
	ArcNode* firstInArc;	//结点第一个弧头结点
	ArcNode* firstOutArc;	//结点第一个弧尾结点

}VertexNode,OList[MaxVertexNum];

typedef struct Graph {OList oList;			//顶点表
	int verNum, arcNum;		//结点个数、弧条数
}GraphOList;

(2)初始化十字链表

/*初始化十字 链表*/
void initOrthList(GraphOList* G) {
	for (int i = 0; i < MaxVertexNum; i++) {
		G->oList[i].firstInArc = NULL;
		G->oList[i].firstOutArc = NULL;
	}
	
}

(3)创建十字链表

1.插入弧尾相同的下一条弧

newNode->tLink = G->oList[Vi - 1].firstOutArc;
G->oList[Vi - 1].firstOutArc = newNode;

2.插入弧头相同的下一条弧

newNode->hLink = G->oList[Vj - 1].firstInArc;
G->oList[Vj - 1].firstInArc = newNode;

3.创建十字链表

/*创建十字链表*/
void CreateOrthList(GraphOList* G) {
	int Vi, Vj;
	WeighType info;

	//输入顶点及弧的数量
	printf("请输入顶点个数及弧条数(空格间隔):");
	scanf("%d%d", &G->verNum, &G->arcNum);
	//插入顶点元素
	for (int i = 0; i < G->verNum; i++) {
		printf("请输入第%d个顶点元素 :",i + 1);
		scanf(" %c", &G->oList[i].data);
	}

	for (int j = 0; j < G->arcNum; j++) {
		printf("请输入第%d条弧的信息 Vi Vj W:(空格间隔):",j);
		scanf("%d%d%d", &Vi, &Vj, &info);

		ArcNode* newNode;		//创建新节点
		newNode = (ArcNode*)malloc(sizeof(ArcNode));
		
		newNode->tailVex = Vi;
		newNode->headVex = Vj;
		newNode->info = info;
        
		/*弧头相同的下一条弧*/
		newNode->tLink = G->oList[Vi - 1].firstOutArc;
		G->oList[Vi - 1].firstOutArc = newNode;
	
		/*弧尾相同的下一条弧*/
		newNode->hLink = G->oList[Vj - 1].firstInArc;
		G->oList[Vj - 1].firstInArc = newNode;

	}
	
}

(4)打印输出

​ 1.按弧头相同

void PrintGraphVertexByHead(GraphOList* G) {
	printf("结点:\n");
	for (int i = 0; i < G->verNum; i++) {

		printf("%d\t%c\t", i + 1, G->oList[i].data);
		ArcNode* p = G->oList[i].firstInArc;
		while (p != NULL) {
			printf("(%d,%d,%d)\t", p->tailVex, p->headVex, p->info);
			p = p->hLink;
		}
		if (p == NULL) {
			printf("^");
		}
		printf("\n\n");
	}
}

​ 2.按弧尾相同

void PrintGraphVertexByTail(GraphOList* G) {
	printf("结点:\n");
	for (int i = 0; i < G->verNum; i++) {

		printf("%d\t%c\t", i + 1, G->oList[i].data);
		ArcNode* p = G->oList[i].firstOutArc;
		while (p != NULL) {
			printf("(%d,%d,%d)\t", p->tailVex, p->headVex,p->info);
			p = p->tLink;
		}
		if (p == NULL) {
			printf("^");
		}
		printf("\n\n");
	}
}

(5)运行截图

在这里插入图片描述

(6)完整代码

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

#define MaxVertexNum 30
typedef int VexLocalType;	//结点位序
typedef char VertexType;	//结点类型
typedef int WeighType;		//权值类型

typedef struct ArcNode {

	VexLocalType tailVex;	//尾结点
	VexLocalType headVex;	//头结点
	struct ArcNode* hLink;	//弧头相同的下一条弧
	struct ArcNode* tLink;	//弧尾相同的下一条弧
	WeighType info;			//权值

}ArcNode;

typedef struct VerNode {

	VertexType data;		//结点元素
	ArcNode* firstInArc;	//结点第一个弧头结点
	ArcNode* firstOutArc;	//结点第一个弧尾结点

}VertexNode,OList[MaxVertexNum];

typedef struct Graph {
	OList oList;			//顶点表
	int verNum, arcNum;		//结点个数、弧条数
}GraphOList;

/*初始化十字 链表*/
void initOrthList(GraphOList* G) {
	for (int i = 0; i < MaxVertexNum; i++) {
		G->oList[i].firstInArc = NULL;
		G->oList[i].firstOutArc = NULL;
	}
}

/*创建十字链表*/
void CreateOrthList(GraphOList* G) {
	int Vi, Vj;
	WeighType info;

	//输入顶点及弧的数量
	printf("请输入顶点个数及弧条数(空格间隔):");
	scanf("%d%d", &G->verNum, &G->arcNum);
	//插入顶点元素
	for (int i = 0; i < G->verNum; i++) {
		printf("请输入第%d个顶点元素 :",i + 1);
		scanf(" %c", &G->oList[i].data);
	}

	for (int j = 0; j < G->arcNum; j++) {
		printf("请输入第%d条弧的信息 Vi Vj W:(空格间隔):",j);
		scanf("%d%d%d", &Vi, &Vj, &info);

		ArcNode* newNode;
		newNode = (ArcNode*)malloc(sizeof(ArcNode));
		
		newNode->tailVex = Vi;
		newNode->headVex = Vj;
		newNode->info = info;
		/*弧头相同的下一条弧*/
		newNode->tLink = G->oList[Vi - 1].firstOutArc;
		G->oList[Vi - 1].firstOutArc = newNode;
	
		/*弧尾相同的下一条弧*/

		newNode->hLink = G->oList[Vj - 1].firstInArc;
		G->oList[Vj - 1].firstInArc = newNode;
	}
}


void PrintGraphVertexByTail(GraphOList* G) {
	printf("结点:\n");
	for (int i = 0; i < G->verNum; i++) {

		printf("%d\t%c\t", i + 1, G->oList[i].data);
		ArcNode* p = G->oList[i].firstOutArc;
		while (p != NULL) {
			printf("(%d,%d,%d)\t", p->tailVex, p->headVex,p->info);
			p = p->tLink;
		}
		if (p == NULL) {
			printf("^");
		}
		printf("\n\n");
	}
}

void PrintGraphVertexByHead(GraphOList* G) {
	printf("结点:\n");
	for (int i = 0; i < G->verNum; i++) {

		printf("%d\t%c\t", i + 1, G->oList[i].data);
		ArcNode* p = G->oList[i].firstInArc;
		while (p != NULL) {
			printf("(%d,%d,%d)\t", p->tailVex, p->headVex, p->info);
			p = p->hLink;
		}
		if (p == NULL) {
			printf("^");
		}
		printf("\n\n");
	}
}

int main() {

	GraphOList* G;
	G = (GraphOList*)malloc(sizeof(GraphOList));
	initOrthList(G);
	CreateOrthList(G);
	PrintGraphVertexByTail(G);
	printf("\n\n");
	PrintGraphVertexByHead(G);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值