图的存储结构——十字链表法
(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);
}