Kruskal算法求MST(最小生成树)

Kruskal算法求最小生成树使用的图的存储结构是图的边表存储结构

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

#define MAX_VERTAX_SIZE 20
#define MAX_EAGE_SIZE 50
#define OK 1
#define ERROR 0

typedef int Status;
typedef char VertaxElemType;

typedef struct EageNode{
	int adjacentVertax;
	int weight;
	struct EageNode* nextEage;
}EageNode,*EageNodePtr;
typedef struct VertaxNode{
	VertaxElemType data;
	EageNodePtr firstEage;
}VertaxNode;
typedef struct GraphAL{
	VertaxNode vertaxNodeArray[MAX_VERTAX_SIZE];
	int vertaxNum;
	int eageNum;
}GraphAL;

typedef struct EageTableNode{
	int eageHead;
	int eageTail;
	int weight;
}EageTableNode;
typedef struct GraphET{
	VertaxElemType vertaxArray[MAX_VERTAX_SIZE];
	EageTableNode eageTable[MAX_EAGE_SIZE];
	int eageNum;
	int vertaxNum;
}GraphET;

int LocateVertax(GraphAL G, VertaxElemType v);
Status CreateGraphAL_UDG_S(GraphAL* G);	
Status FromAdjacencyListToEageTable(GraphAL G, GraphET* G_1);
void PrintEageTable(GraphET G);
void PrintAdjacencyList(GraphAL G);

int LocateVertax(GraphAL G, VertaxElemType v){
	int i;
	for( i = 0; i < G.vertaxNum; i++ ){
		if( G.vertaxNodeArray[i].data == v )
			return i;
	}
	return -1;
}
//创建无向图,使用邻接矩阵存储
Status CreateGraphAL_UDG_S(GraphAL* G){		//相同的边只存储一次,方便转化为边表结构
	int i,index_v,index_w,weight;
	VertaxElemType v,w;
	EageNodePtr vPtr,wPtr;
	printf("  Create UndiGraph with Adjacecy List\n");
	printf("please enter the number of VERTAX and EAGE:");
	scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));

	printf("ok, please enter the value of vertaxes,Seperated by Space\n   :");
	for( i = 0; i < G->vertaxNum; i++ ){
		scanf("%c%*c", &(G->vertaxNodeArray[i].data));
		G->vertaxNodeArray[i].firstEage = NULL;
	}
	for( i = 0; i < G->eageNum; i++ ){
		printf("ok, please enter the two VERTAX and WEIGHT of EAGE %d\n note: Seperated by Space :", i+1);
		scanf("%c %c %d%*c", &v,&w,&weight);
		index_v = LocateVertax(*G, v);
		index_w = LocateVertax(*G, w);
		vPtr = (EageNode*)malloc(sizeof(struct EageNode));
		if( !vPtr )
			return ERROR;
		vPtr->adjacentVertax = index_w;
		vPtr->weight = weight;
		vPtr->nextEage = G->vertaxNodeArray[index_v].firstEage;
		G->vertaxNodeArray[index_v].firstEage = vPtr;
		/*
		wPtr = (EageNode*)malloc(sizeof(struct EageNode));
		if( !wPtr )
			return ERROR;
		wPtr->adjacentVertax = index_v;
		wPtr->weight = weight;
		wPtr->nextEage = G->vertaxNodeArray[index_w].firstEage;
		G->vertaxNodeArray[index_w].firstEage = wPtr;
		*/
	}
	//PrintAdjacencyList(*G);
	return OK;
}
//将图的邻接表表示转化为图的边表表示,kruskal算法将要使用这种结构
Status FromAdjacencyListToEageTable(GraphAL G, GraphET* G_1){
	int i,j;
	EageNodePtr p;
	int counterOfEage = 0;
	G_1->eageNum = G.eageNum;
	G_1->vertaxNum = G.vertaxNum;
	for( i = 0; i < G.vertaxNum; i++ )
		G_1->vertaxArray[i] = G.vertaxNodeArray[i].data;
	for( i = 0; i < G.vertaxNum; i++ ){
		p = G.vertaxNodeArray[i].firstEage;
		while( p ){
			G_1->eageTable[counterOfEage].eageHead = i;
			G_1->eageTable[counterOfEage].eageTail = p->adjacentVertax;
			G_1->eageTable[counterOfEage].weight = p->weight;
			counterOfEage++;
			p = p->nextEage;
		}
	}
	//PrintEageTable(*G_1);
	//排序,按权值从小到大
	EageTableNode temp;
	for( i = 0; i < G_1->eageNum - 1; i++ ){
		for( j = i; j < G_1->eageNum; j++ ){
			if( G_1->eageTable[i].weight > G_1->eageTable[j].weight ){
				temp.eageHead = G_1->eageTable[i].eageHead;
				temp.eageTail = G_1->eageTable[i].eageTail;
				temp.weight = G_1->eageTable[i].weight;
				G_1->eageTable[i].eageHead = G_1->eageTable[j].eageHead;
				G_1->eageTable[i].eageTail = G_1->eageTable[j].eageTail;
				G_1->eageTable[i].weight = G_1->eageTable[j].weight;
				G_1->eageTable[j].eageHead = temp.eageHead;
				G_1->eageTable[j].eageTail = temp.eageTail;
				G_1->eageTable[j].weight = temp.weight;
			}
		}
	}
	if( counterOfEage == G_1->eageNum ){
		return OK;
	}
	else{
		return ERROR;
	}
}
void PrintEageTable(GraphET G){
	int i;
	printf("\nPrint Eage Table\n");
	printf("--------------------------------------------------\n");
	printf("| order | startVertax  | endVertax  | eageWeight |\n");
	for( i = 0; i < G.eageNum; i++ ){
		printf("|------------------------------------------------|\n");
		printf("|   %d   |      %d       |      %d     |     %d      |\n", i+1, G.eageTable[i].eageHead, G.eageTable[i].eageTail, G.eageTable[i].weight);
	}
	printf("--------------------------------------------------\n");
}
void PrintAdjacencyList(GraphAL G){
	int i;
	EageNodePtr p;
	for( i = 0; i < G.vertaxNum; i++ ){
		printf(" %d %c : ",i+1, G.vertaxNodeArray[i].data);
		p = G.vertaxNodeArray[i].firstEage;	
		while( p != NULL ){
			printf("--->%d weight(%d)", p->adjacentVertax+1,p->weight);
			p = p->nextEage;
		}
		printf("\n");
	}
}

int getindex(int* array, int index){
	while( array[index] != 0 ){
		index = array[index];
	}
	return index;
}
Status Kruskal(GraphET G){
	int i;
	int MSTed[MAX_VERTAX_SIZE];	//这个数组是Kruskal算法的关键
	int v,w;
	for( i = 0; i < G.vertaxNum; i++ )
		MSTed[i] = 0;
	printf("MST(Minimum Cost Spanning Trss) by Kruskal\n");
	for( i = 0; i < G.eageNum; i++ ){
		v = getindex(MSTed, G.eageTable[i].eageHead);
		w = getindex(MSTed, G.eageTable[i].eageTail);
		if( v != w ){
			printf("(%c, %c) weight(%d)\n", G.vertaxArray[G.eageTable[i].eageHead], G.vertaxArray[G.eageTable[i].eageTail], G.eageTable[i].weight);
			MSTed[v] = w;
		}
	}
	return OK;
}
int main(){
	GraphAL G;
	CreateGraphAL_UDG_S(&G);
	GraphET G_1;
	FromAdjacencyListToEageTable(G, &G_1);
	PrintEageTable(G_1);
	Kruskal(G_1);
	return OK;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值