严蔚敏数据结构Prim算法

#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 ArcCell
{
	VRType adj;
	InfoType* info;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{
	VertexType vexs[MAX_VERTEX_NUM];
	AdjMatrix arcs;
	int vexnum, arcnum;
	GraphKind kind;
}MGraph;
Status CreatGraph(MGraph* G)
{
	printf("请输入图的类型\n");
	scanf("%d", &(G->kind));
	switch (G->kind)
	{
	case DG:return(CreatDG(G)); break;
	case DN:return(CreatDN(G)); break;
	case UDG:return(CreatUDG(G)); break;
	case UDN:return(CreatUDN(G)); break;
	default: return ERROR;
	}
}
Status CreatDG(MGraph* G)
{
	printf("请依次输入图的总结点数,弧数,以及是弧是否需要额外信息,无额外信息输入0,有额外信息输入1\n");
	int info;
	scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
	getchar();
	printf("请输入%d个顶点的描述\n", G->vexnum);
	for (int i = 0; i < G->vexnum; i++)
	{
		G->vexs[i] = (VertexType)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->vexs[i]) exit(OVERFLOW);
		gets(G->vexs[i]);
	}
	for(int i=0;i<G->vexnum;i++)
		for (int j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = 0;
			G->arcs[i][j].info = NULL;
		}
	int tail, head;
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	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(ch, G->vexs[j]) == 0)
			{
				tail = j;
				break;
			}
		printf("请输入它的弧头顶点描述\n");
		gets(ch);
		for (int j = 0; j < G->vexnum; j++)
			if (strcmp(ch, G->vexs[j]) == 0)
			{
				head = j;
				break;
			}
		G->arcs[tail][head].adj = 1;
		if (info)
		{
			G->arcs[tail][head].info = (InfoType*)malloc(sizeof(InfoType) * MAXINFOLEN);
			if (!G->arcs[tail][head].info) exit(OVERFLOW);
			printf("请输入其信息\n");
			gets(G->arcs[tail][head].info);
		}
	}
	return OK;
}
Status CreatDN(MGraph* G)
{
	printf("请依次输入图的总结点数,弧数,以及是弧是否需要额外信息,无额外信息输入0,有额外信息输入1\n");
	int info;
	scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
	getchar();
	printf("请输入%d个顶点的描述\n", G->vexnum);
	for (int i = 0; i < G->vexnum; i++)
	{
		G->vexs[i] = (VertexType)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->vexs[i]) exit(OVERFLOW);
		gets(G->vexs[i]);
	}
	for (int i = 0; i < G->vexnum; i++)
		for (int j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = INFINITY;
			G->arcs[i][j].info = NULL;
		}
	int tail, head;
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	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(ch, G->vexs[j]) == 0)
			{
				tail = j;
				break;
			}
		printf("请输入它的弧头顶点描述\n");
		gets(ch);
		for (int j = 0; j < G->vexnum; j++)
			if (strcmp(ch, G->vexs[j]) == 0)
			{
				head = j;
				break;
			}
		printf("请输入弧的权值\n");
		scanf("%d", &(G->arcs[tail][head]));
		getchar();
		if (info)
		{
			G->arcs[tail][head].info = (InfoType*)malloc(sizeof(InfoType) * MAXINFOLEN);
			if (!G->arcs[tail][head].info) exit(OVERFLOW);
			printf("请输入其信息\n");
			gets(G->arcs[tail][head].info);
		}
	}
	return OK;
}
Status CreatUDG(MGraph* G)
{
	printf("请依次输入图的总结点数,弧数,以及是弧是否需要额外信息,无额外信息输入0,有额外信息输入1\n");
	int info;
	scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
	getchar();
	printf("请输入%d个顶点的描述\n", G->vexnum);
	for (int i = 0; i < G->vexnum; i++)
	{
		G->vexs[i] = (VertexType)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->vexs[i]) exit(OVERFLOW);
		gets(G->vexs[i]);
	}
	for (int i = 0; i < G->vexnum; i++)
		for (int j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = 0;
			G->arcs[i][j].info = NULL;
		}
	int vex1, vex2;
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	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(ch, G->vexs[j]) == 0)
			{
				vex1 = j;
				break;
			}
		printf("请输入它所依附的第二个顶点的顶点描述\n");
		gets(ch);
		for (int j = 0; j < G->vexnum; j++)
			if (strcmp(ch, G->vexs[j]) == 0)
			{
				vex2 = j;
				break;
			}
		G->arcs[vex1][vex2].adj = 1;
		G->arcs[vex2][vex1].adj = 1;
		if (info)
		{
			G->arcs[vex1][vex2].info = (InfoType*)malloc(sizeof(InfoType) * MAXINFOLEN);
			if (!G->arcs[vex1][vex2].info) exit(OVERFLOW);
			printf("请输入其信息\n");
			gets(G->arcs[vex1][vex2].info);
			G->arcs[vex2][vex1].info = (InfoType*)malloc(sizeof(InfoType) * MAXINFOLEN);
			if (!G->arcs[vex2][vex1].info) exit(OVERFLOW);
			strcpy(G->arcs[vex2][vex1].info, G->arcs[vex1][vex2].info);
		}
	}
	return OK;
}
Status CreatUDN(MGraph* G)
{
	printf("请依次输入图的总结点数,弧数,以及是弧是否需要额外信息,无额外信息输入0,有额外信息输入1\n");
	int info;
	scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
	getchar();
	printf("请输入%d个顶点的描述\n", G->vexnum);
	for (int i = 0; i < G->vexnum; i++)
	{
		G->vexs[i] = (VertexType)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->vexs[i]) exit(OVERFLOW);
		gets(G->vexs[i]);
	}
	for (int i = 0; i < G->vexnum; i++)
		for (int j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = INFINITY;
			G->arcs[i][j].info = NULL;
		}
	int vex1, vex2;
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	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(ch, G->vexs[j]) == 0)
			{
				vex1 = j;
				break;
			}
		printf("请输入它所依附的第二个顶点的顶点描述\n");
		gets(ch);
		for (int j = 0; j < G->vexnum; j++)
			if (strcmp(ch, G->vexs[j]) == 0)
			{
				vex2 = j;
				break;
			}
		printf("请输入此弧权值\n");
		scanf("%d", &(G->arcs[vex1][vex2].adj));
		getchar();
		G->arcs[vex2][vex1].adj = G->arcs[vex1][vex2].adj;
		if (info)
		{
			G->arcs[vex1][vex2].info = (InfoType*)malloc(sizeof(InfoType) * MAXINFOLEN);
			if (!G->arcs[vex1][vex2].info) exit(OVERFLOW);
			printf("请输入其信息\n");
			gets(G->arcs[vex1][vex2].info);
			G->arcs[vex2][vex1].info = (InfoType*)malloc(sizeof(InfoType) * MAXINFOLEN);
			if (!G->arcs[vex2][vex1].info) exit(OVERFLOW);
			strcpy(G->arcs[vex2][vex1].info, G->arcs[vex1][vex2].info);
		}
	}
	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;
}

void PreOrderTraverse_MinSpanTree(CSTree* T, char* ch, CSTree* p)
{
	SqStack S;
	InitStack(&S);
	CSNode* q = (*T);
	while (q || !StackEmpty(S))
	{
		if (q)
		{
			Push(&S, q);
			if (strcmp(ch, q->data) == 0)
			{
				*p = (CSTree)malloc(sizeof(CSNode));
				if (!(*p)) exit(OVERFLOW);
				*p = q;
				break;
			}
			q = q->firstchild;
		}
		else
		{
			Pop(&S, &q);
			q = q->nextsibling;
		}
	}
}
void MinSpanTree(MGraph G, VertexType u, CSTree* T)
{
	struct
	{
		VertexType adjvex;
		VRType lowcost;
	}closeedge[MAX_VERTEX_NUM];
	int k;
	for (int i = 0; i < G.vexnum; i++)
		if (strcmp(u, G.vexs[i]) == 0)
		{
			k = i;
			break;
		}
	for (int i = 0; i < G.vexnum; i++)
	{
		if (i != k)
		{
			closeedge[i].lowcost = G.arcs[k][i].adj;
			closeedge[i].adjvex = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
			if (!closeedge[i].adjvex) exit(OVERFLOW);
			strcpy(closeedge[i].adjvex, u);
		}
	}
	(*T) = (CSTree)malloc(sizeof(CSNode));
	if (!(*T)) exit(OVERFLOW);
	(*T)->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!(*T)->data) exit(OVERFLOW);
	strcpy((*T)->data, u);
	(*T)->firstchild = NULL;
	(*T)->nextsibling = NULL;
	closeedge[k].lowcost = 0;
	closeedge[k].adjvex = NULL;
	int count = 1;
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	CSNode* p;
	while (count < G.vexnum)
	{
		int mincost = INFINITY;
		int min;
		for (int i = 0; i < G.vexnum; i++)
			if (closeedge[i].lowcost && closeedge[i].lowcost < mincost)
			{
				mincost = closeedge[i].lowcost;
				min = i;
			}
		strcpy(ch, closeedge[min].adjvex);
		PreOrderTraverse_MinSpanTree(T, ch, &p);          //在树T中找到与ch相同的节点并返回它的指针
		CSNode* q;
		q = (CSNode*)malloc(sizeof(CSNode));
		if (!q) exit(OVERFLOW);
		q->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!q->data) exit(OVERFLOW);
		strcpy(q->data, G.vexs[min]);
		if (p->firstchild)
		{
			p = p->firstchild;
			while (p->nextsibling)
				p = p->nextsibling;
			p->nextsibling = q;
			q->firstchild = NULL;
			q->nextsibling = NULL;
		}
		else
		{
			p->firstchild = q;
			q->nextsibling = NULL;
			q->firstchild = NULL;
		}
		closeedge[min].lowcost = 0;
		closeedge[min].adjvex = NULL;
		for (int j = 0; j < G.vexnum; j++)
			if (closeedge[j].lowcost && G.arcs[min][j].adj < closeedge[j].lowcost)
			{
				closeedge[j].lowcost = G.arcs[min][j].adj;
				strcpy(closeedge[j].adjvex, G.vexs[min]);
			}
		count++;
	}
}
//Prim算法主函数
int main()
{
	MGraph G;
	CSTree* T;
	T = (CSTree*)malloc(sizeof(CSTree));
	if (!T) exit(OVERFLOW);
	CreatGraph(&G);
	printf("\t");
	for (int i = 0; i < G.vexnum; i++)
		printf("V%d\t", i + 1);
	printf("\n\n");
	for (int i = 0; i < G.vexnum; i++)
	{
		printf("V%d\t", i + 1);
		for (int j = 0; j < G.vexnum; j++)
			printf("%d\t", G.arcs[i][j].adj);
		printf("\n\n\n");
	}
	char* u = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!u) exit(OVERFLOW);
	strcpy(u, G.vexs[0]);
	MinSpanTree(G, u, T);
	PrintCSTree_LevelOrder(*T);
	return 0;
}

输入:

3
6 10 0
V1
V2
V3
V4
V5
V6
V1
V2
6
V1
V3
1
V1
V4
5
V2
V3
5
V3
V4
5
V2
V5
3
V3
V5
6
V5
V6
6
V3
V6
4
V4
V6
2

原图:

 结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值