严蔚敏数据结构无向图连通分量及生成树

本文档详细介绍了如何使用C语言实现邻接表结构来存储图,并演示了无向图的连通分量检测与生成树算法,通过DFS方法构建孩子兄弟树(CSTree)的层次顺序输出。

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

#include <stdio.h>
#include <string.h>
#define OK 1
#define INFINITY 32767
#define MAX_VERTEX_NUM 30
#define MAXINFOLEN 30
#define ERROR 0
#define OVERFLOW -1
#define MAXVERTEXLEN 30
#define FALSE 0
#define TRUE 1
typedef int Status;
typedef enum { DG, DN, UDG, UDN }GraphKind;
typedef int VRType;
typedef int InfoType;
typedef char* VertexType;
//邻接表存储图结构
typedef struct ArcNode
{
	struct ArcNode* nextarc;
	InfoType* info;
	int adjvex;
}ArcNode;
typedef struct VNode
{
	VertexType data;
	ArcNode* firstnode;
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
	AdjList vertices;
	int vexnum, arcnum;
	GraphKind kind;
}ALGraph;
void CreatGraph_AL(ALGraph* G)
{
	printf("请输入邻接表存储图的种类,且只能存储有向图(0)与无向图(2)\n");
	scanf("%d", &(G->kind));
	int info;
	printf("请依次输入图的节点数,弧数,是否需要弧的信息\n");
	scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
	getchar();
	for (int i = 0; i < G->vexnum; i++)
	{
		printf("请输入图的第%d个节点的描述\n", i + 1);
		G->vertices[i].data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->vertices[i].data) exit(OVERFLOW);
		gets(G->vertices[i].data);
		G->vertices[i].firstnode = NULL;
	}
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	if (G->kind == DG)
	{
		int tail, head;
		for (int i = 0; i < G->arcnum; i++)
		{
			printf("请输入第%d个节点关系\n", i + 1);
			printf("请输入弧尾描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					tail = j;
					break;
				}
			}
			printf("请输入弧头描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					head = j;
					break;
				}
			}
			ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
			if (!p) exit(OVERFLOW);
			p->adjvex = head;
			ArcNode* s = G->vertices[tail].firstnode;
			if (!s)
			{
				p->nextarc = G->vertices[tail].firstnode;
				G->vertices[tail].firstnode = p;
			}
			else
			{
				while (s->nextarc)
					s = s->nextarc;
				p->nextarc = s->nextarc;
				s->nextarc = p;
			}
			if (info)
			{
				printf("请输入弧的描述信息\n");
				p->info = (int*)malloc(sizeof(int));
				if (!p->info) exit(OVERFLOW);
				scanf("%d", p->info);
				getchar();
			}
		}
	}
	else
	{
		int vex1, vex2;
		for (int i = 0; i < G->arcnum; i++)
		{
			printf("请输入第%d个节点关系\n", i + 1);
			printf("请输入第一个相关节点描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					vex1 = j;
					break;
				}
			}
			printf("请输入第二个相关节点描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					vex2 = j;
					break;
				}
			}
			ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
			if (!p) exit(OVERFLOW);
			p->adjvex = vex1;
			ArcNode* s = G->vertices[vex2].firstnode;
			if (!s)
			{
				p->nextarc = G->vertices[vex2].firstnode;
				G->vertices[vex2].firstnode = p;
			}
			else
			{
				while (s->nextarc)
					s = s->nextarc;
				p->nextarc = s->nextarc;
				s->nextarc = p;
			}
			if (info)
			{
				printf("请输入弧的描述信息\n");
				p->info = (int*)malloc(sizeof(int));
				if (!p->info) exit(OVERFLOW);
				scanf("%d", p->info);
				getchar();
			}
			ArcNode* q = (ArcNode*)malloc(sizeof(ArcNode));
			if (!q) exit(OVERFLOW);
			q->adjvex = vex2;
			s = G->vertices[vex1].firstnode;
			if (!s)
			{
				q->nextarc = G->vertices[vex1].firstnode;
				G->vertices[vex1].firstnode = q;
			}
			else
			{
				while (s->nextarc)
					s = s->nextarc;
				q->nextarc = s->nextarc;
				s->nextarc = q;
			}
			if (info)
			{
				printf("请输入弧的描述信息\n");
				p->info = (int*)malloc(sizeof(int) * MAXINFOLEN);
				if (!p->info) exit(OVERFLOW);
				scanf("%d", p->info);
				getchar();
			}
		}
	}
}


//孩子兄弟树的数据结构描述
typedef char* TElemType;
typedef struct CSNode
{
	TElemType data;
	struct CSNode* firstchild, * nextsibling;
}CSNode, * CSTree;



//队列函数
typedef CSTree QElemType;
typedef struct QNode
{
	QElemType data;
	struct QNode* next;
}QNode, * QueuePtr;
typedef struct
{
	QueuePtr front, rear;
}LinkQueue;
Status InitQueue(LinkQueue* Q)
{
	Q->front = (QNode*)malloc(sizeof(QNode));
	if (!Q->front) exit(OVERFLOW);
	Q->rear = Q->front;
	return OK;
}
Status EnQueue(LinkQueue* Q, QElemType e)
{
	QNode* p;
	p = (QNode*)malloc(sizeof(QNode));
	if (!p) exit(OVERFLOW);
	p->data = e;
	Q->rear->next = p;
	Q->rear = p;
	p->next = NULL;
	return OK;
}
Status DeQueue(LinkQueue* Q, QElemType* e)
{
	if (Q->front == Q->rear)
		return ERROR;
	*e = Q->front->next->data;
	if (Q->rear == Q->front->next)
		Q->rear = Q->front;
	QNode* p = Q->front->next;
	Q->front->next = p->next;
	free(p);
	return OK;
}
Status QueueEmpty(LinkQueue Q)
{
	if (Q.front == Q.rear)
		return TRUE;
	else
		return FALSE;
}
void PrintQueue(LinkQueue Q)
{
	QNode* p = Q.front->next;
	if (!p)
		printf("空\n");
	else
	{
		while (p)
		{
			printf("%d\t", p->data + 1);
			p = p->next;
		}
		printf("\n");
	}
}



void PrintCSTree_LevelOrder(CSTree T)
{
    printf("孩子兄弟树层序输入为\n");
	LinkQueue* Q;
	Q = (LinkQueue*)malloc(sizeof(LinkQueue));
	if (!Q) exit(OVERFLOW);
	InitQueue(Q);
	EnQueue(Q, T);
	QElemType* p;
	p = (QElemType*)malloc(sizeof(QElemType));
	if (!p) exit(OVERFLOW);
	while (!QueueEmpty(*Q))
	{
		DeQueue(Q, p);
		puts((*p)->data);
		if ((*p)->firstchild)
			EnQueue(Q, (*p)->firstchild);
		if ((*p)->nextsibling)
			EnQueue(Q, (*p)->nextsibling);
	}
}
//无向图连通分量与生成树
int visited[MAX_VERTEX_NUM];
void DFSTree(ALGraph G, CSTree T, int m)
{
	visited[m] = TRUE;
	ArcNode* p = G.vertices[m].firstnode;
	int first = 1;
	CSNode* q, * r;
	while (p)
	{
		int i = p->adjvex;
		if (!visited[i])
		{
		    q = (CSNode*)malloc(sizeof(CSNode));
			if (!q) exit(OVERFLOW);
			q->firstchild = NULL;
			q->nextsibling = NULL;
			q->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
			if (!q->data) exit(OVERFLOW);
			strcpy(q->data, G.vertices[i].data);
			if (first == 1)
			{
				T->firstchild = q;
				r = q;
				first = 0;
				DFSTree(G, q, i);
			}
			else
			{
				r->nextsibling = q;
				r = q;
				DFSTree(G, q, i);
			}
		}
		p = p->nextarc;
	}
}
void DFSForest(ALGraph G, CSTree* T)
{
	int first = 1;
	for (int i = 0; i < G.vexnum; i++)
		visited[i] = FALSE;
	CSNode* q;
	for (int i = 0; i < G.vexnum; i++)
	{
		if (!visited[i])
		{
			CSNode* p;
			p = (CSNode*)malloc(sizeof(CSNode));
			if (!p) exit(OVERFLOW);
			p->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
			if (!p->data) exit(OVERFLOW);
			strcpy(p->data, G.vertices[i].data);
			p->firstchild = NULL;
			p->nextsibling = NULL;
			if (first == 1)
			{
				*T = p;
				q = p;
				first = 0;
			}
			else
			{
				q->nextsibling = p;
				q = p;
			}
			DFSTree(G, p, i);
		}
	}
}
int main()
{
	ALGraph G;
	CreatGraph_AL(&G);
	ArcNode* p;
	for (int j = 0; j < G.vexnum; j++)
	{
		printf("---------V%d的邻接节点---------\n", j + 1);
		p = G.vertices[j].firstnode;
		while (p)
		{
			int i = p->adjvex;
			puts(G.vertices[i].data);
			p = p->nextarc;
		}
	}
	CSTree* T;
	T = (CSTree*)malloc(sizeof(CSTree));
	if (!T) exit(OVERFLOW);
	DFSForest(G, T);
	PrintCSTree_LevelOrder(*T);
	return 0;
}

输入:(P168)

2
8 9 0
V1
V2
V3
V4
V5
V6
V7
V8
V1
V2
V1
V3
V2
V4
V2
V5
V4
V8
V5
V8
V3
V6
V3
V7
V6
V7

输出:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值