严蔚敏数据结构有向图强连通分量

 

#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 ArcBox
{
	int tailvex, headvex;
	struct ArcBox* hlink, * tlink;
	InfoType* info;
}ArcBox;
typedef struct VexNode
{
	VertexType data;
	ArcBox* firstin, * firstout;
}VexNode;
typedef struct
{
	VexNode xlist[MAX_VERTEX_NUM];
	int vexnum, arcnum;
}OLGraph;
Status CreatDG_OL(OLGraph* G)
{
	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->xlist[i].data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->xlist) exit(OVERFLOW);
		gets(G->xlist[i].data);
		G->xlist[i].firstin = NULL;
		G->xlist[i].firstout = NULL;
	}
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	int tail = 1000, head = 1000;
	for (int i = 0; i < G->arcnum; i++)
	{
		ArcBox* p;
		p = (ArcBox*)malloc(sizeof(ArcBox));
		if (!p) exit(OVERFLOW);
		printf("请输入弧尾的节点描述\n");
		gets(ch);
		for (int j = 0; j < G->vexnum; j++)
		{
			if (strcmp(ch, G->xlist[j].data) == 0)
			{
				tail = j;
				break;
			}
		}
		p->tailvex = tail;
		p->tlink = G->xlist[tail].firstout;
		G->xlist[tail].firstout = p;
		printf("请输入弧头的节点描述\n");
		gets(ch);
		for (int j = 0; j < G->vexnum; j++)
		{
			if (strcmp(ch, G->xlist[j].data) == 0)
			{
				head = j;
				break;
			}
		}
		p->headvex = head;
		p->hlink = G->xlist[i].firstin;
		G->xlist[head].firstin = p;
		if (info)
		{
			printf("请输入弧的描述信息\n");
			p->info = (int*)malloc(sizeof(int));
			if (!p->info) exit(OVERFLOW);
			scanf("%d", p->info);
			getchar();
		}
		else
			p->info = NULL;
	}
	return OK;
}
//孩子兄弟树的数据结构描述
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);
	}
}







//栈的数据结构及函数
#define STACK_INIT_SIZE 100
#define STACK_INCREASMENT 10
typedef int SElemType;
typedef struct
{
	SElemType* base, * top;
	int stacksize;
}SqStack;
Status InitStack(SqStack* S)
{
	S->base = (SElemType*)malloc(sizeof(SElemType) * STACK_INIT_SIZE);
	if (!S->base) exit(OVERFLOW);
	S->top = S->base;
	S->stacksize = STACK_INIT_SIZE;
}
Status Push(SqStack* S, SElemType e)
{
	if (S->top - S->base > S->stacksize)
	{
		S->base = (SElemType*)realloc(S->base, sizeof(SElemType) * (S->stacksize + STACK_INCREASMENT));
		if (!S->base) exit(OVERFLOW);
		S->stacksize += STACK_INCREASMENT;
	}
	*(S->top) = e;
	S->top++;
	return OK;
}
Status Pop(SqStack* S, SElemType* e)
{
	if (S->base == S->top)
		return ERROR;
	S->top--;
	*e = *(S->top);
	return OK;
}
Status StackEmpty(SqStack S)
{
	if (S.base == S.top)
		return TRUE;
	else
		return FALSE;
}




//求强连通分量辅助数据结构
typedef struct
{
	char ch[MAXVERTEXLEN];
	int i;
}Help;
//找有向图中的强连通分量(十字链表表示有向图)
int visited[MAX_VERTEX_NUM];
Help finished[MAX_VERTEX_NUM];
void Convert(OLGraph G1, OLGraph* G2)
{
	G2->arcnum = G1.arcnum;
	G2->vexnum = G1.vexnum;
	for (int i = 0; i < G2->vexnum; i++)
	{
		G2->xlist[i].firstin = NULL;
		G2->xlist[i].firstout = NULL;
		G2->xlist[i].data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G2->xlist[i].data) exit(OVERFLOW);
		strcpy(G2->xlist[i].data, G1.xlist[i].data);
	}
	for (int i = 0; i < G2->vexnum; i++)
	{
		ArcBox* p = G1.xlist[i].firstout;
		while (p)
		{
			ArcBox* q = (ArcBox*)malloc(sizeof(ArcBox));
			if (!q) exit(OVERFLOW);
			q->headvex = i;
			q->tailvex = p->headvex;
			q->hlink = G2->xlist[i].firstin;
			G2->xlist[i].firstin = q;
			q->tlink = G2->xlist[p->headvex].firstout;
			G2->xlist[p->headvex].firstout = q;
			if (p->info)
			{
				q->info = (char*)malloc(sizeof(char) * MAXINFOLEN);
				if (!q->info) exit(OVERFLOW);
			}
			p = p->tlink;
		}
	}
}
void DFSTree_OL(OLGraph G, int m, CSTree T)
{
	visited[m] = TRUE;
	int first = 1;
	ArcBox* r = G.xlist[m].firstout;
	CSNode* q;
	while (r)
	{
		if (!visited[r->headvex])
		{
			CSNode* p = (CSTree)malloc(sizeof(CSNode));
			if (!p) exit(OVERFLOW);
			p->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
			if (!p->data) exit(OVERFLOW);
			strcpy(p->data, G.xlist[r->headvex].data);
			if (first == 1)
			{
				T->firstchild = p;
				q = p;
				q->nextsibling = NULL;
				first = 0;
			}
			else
			{
				q->nextsibling = p;
				q = p;
				q->nextsibling = NULL;
			}
			DFSTree_OL(G, r->headvex, q);
		}
	r = r->tlink;
	}
	if (first == 1)
		T->firstchild = NULL;
}
void DFSForest_OL(OLGraph G1, CSTree* T)
{
	int first = 1;
	for (int i = 0; i < G1.vexnum; i++)
		visited[i] = FALSE;
	CSNode* q;
	for (int i = 0; i < G1.vexnum; i++)
	{
		if (!visited[i])
		{
			CSTree p = (CSTree)malloc(sizeof(CSNode));
			if (!p) exit(OVERFLOW);
			p->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
			if (!p->data) exit(OVERFLOW);
			strcpy(p->data, G1.xlist[i].data);
			if (first == 1)
			{
				(*T) = p;
				first = 0;
				q = p;
				(*T)->nextsibling = NULL;
			}
			else
			{
				q->nextsibling = p;
				q = p;
				q->nextsibling = NULL;
			}
			DFSTree_OL(G1, i, q);
		}
	}
}
void PostOrderTraverse_CS(CSTree T, SqStack* S)
{
	if (T)
	{
		int i = 0;
		CSNode* p = T->firstchild;
		CSNode* q = p;
		while (q)
		{
			PostOrderTraverse_CS(q, S);
			q = q->nextsibling;
		}
		Push(S, T->data);
		while (strcmp(finished[i].ch, T->data) != 0)
			i++;
		finished[i].i = 1;
	}
}
void DFS_OL(OLGraph G, int m)
{
	finished[m].i = 2;
	printf("%s\t", G.xlist[m].data);
	ArcBox* p = G.xlist[m].firstout;
	while (p)
	{
		if (finished[p->headvex].i == 1)
			DFS_OL(G, p->headvex);
		p = p->tlink;
	}
}
void DFS_OL_Verse(OLGraph G, SqStack* S)
{
	char* ch = (char*)malloc(sizeof(char) * MAXINFOLEN);
	if (!ch) exit(OVERFLOW);
	while (!StackEmpty(*S))
	{
		Pop(S, &ch);
		int i = 0;
		while (strcmp(ch, G.xlist[i].data) != 0)
			i++;
		if (finished[i].i == 1)
		{
			printf("一个连通分量的所有节点描述为:\n");
			DFS_OL(G, i);
			printf("\n");
		}
	}
}
int main()
{
	OLGraph* G1;
	G1 = (OLGraph*)malloc(sizeof(OLGraph));
	if (!G1) exit(OVERFLOW);
	CreatDG_OL(G1);
	printf("G1的指针指向\n");
	for (int i = 0; i < G1->vexnum; i++)
	{
		ArcBox* p = G1->xlist[i].firstout;
		while (p)
		{
			printf("%s->%s\n", G1->xlist[i].data, G1->xlist[p->headvex].data);
			p = p->tlink;
		}
	}
	OLGraph* G2;
	G2 = (OLGraph*)malloc(sizeof(OLGraph));
	if (!G2) exit(OVERFLOW);
	Convert(*G1, G2);
	printf("G2的指针指向\n");
	for (int i = 0; i < G2->vexnum; i++)
	{
		ArcBox* p = G2->xlist[i].firstout;
		while (p)
		{
			printf("%s->%s\n", G2->xlist[i].data, G2->xlist[p->headvex].data);
			p = p->tlink;
		}
	}
	CSTree T;
	DFSForest_OL(*G2, &T);
	PrintCSTree_LevelOrder(T);
	SqStack S;
	InitStack(&S);
	CSNode* p = T;
	for (int i = 0; i < G2->vexnum; i++)
	{
		strcpy(finished[i].ch, G2->xlist[i].data);
		finished[i].i = 0;
	}
	while (p)
	{
		PostOrderTraverse_CS(p, &S);
		DFS_OL_Verse(*G1, &S);
		p = p->nextsibling;
	}
	return 0;
}

输入:

13 22 0
V0
V1
V2
V3
V4
V5
V6
V7
V8
V9
V10
V11
V12
V0
V5
V0
V6
V0
V1
V2
V0
V2
V3
V3
V2
V3
V5
V4
V2
V4
V3
V5
V4
V6
V4
V7
V6
V6
V9
V4
V11
V7
V8
V8
V7
V8
V9
V9
V10
V9
V11
V11
V12
V10
V12
V12
V9

原图:

输出:

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值