1. 程式人生 > >最小生成樹(鄰接表寫法)

最小生成樹(鄰接表寫法)

#include<stdio.h>
#include<stdlib.h>
#define max 20
typedef struct ArcNode
{
	int adjvex;
	struct ArcNode *nextarc;
	int info;
 } ArcNode;
typedef struct VertexNode
{
	char data;
	ArcNode *firstarc;
}VertexNode;
typedef struct{
	VertexNode vertex[max];
	int vexnum,arcnum;
}AdjList;
AdjList *G=(AdjList *)malloc(sizeof(AdjList));
AdjList *primtree=(AdjList *)malloc(sizeof(AdjList));
int locatevertex(AdjList *G,char x)
{
	for(int i=0;i<G->vexnum;i++)
	{
		if(G->vertex[i].data==x)
		return i;
	} 
	return -1;
}
int creategraph(AdjList *G)                 /*建立一張圖*/ 
{
	int i,j,k,power;
	char v1,v2;
	printf("請輸入頂點數和邊數:\n");
	scanf("%d%d",&G->vexnum,&G->arcnum);
	fflush(stdin);
	printf("請輸入頂點:\n");
	for(i=0;i<G->vexnum;i++)
	{
		fflush(stdin);
		scanf("%c",&G->vertex[i].data);
		G->vertex[i].firstarc=NULL;
	 } 
	 printf("請輸入邊和權值:\n");
	 for(i=0;i<G->arcnum;i++)
	 {
	 	fflush(stdin);
	 	scanf("%c %c%d",&v1,&v2,&power);
	 	j=locatevertex(G,v1);
	 	k=locatevertex(G,v2);
	 	ArcNode *arc=(ArcNode *)malloc(sizeof(ArcNode));
	 	arc->adjvex=k;
	 	arc->info=power;
	 	arc->nextarc=G->vertex[j].firstarc;
	 	G->vertex[j].firstarc=arc;
	 	
	 	arc=(ArcNode *)malloc(sizeof(ArcNode));
	 	arc->adjvex=j;
	 	arc->info=power;
	 	arc->nextarc=G->vertex[k].firstarc;
	 	G->vertex[k].firstarc=arc;
	 	
	}	
}
void initprimtree(AdjList *G,AdjList *primtree)            /*初始化最小生成樹*/ 
{ 
	int i;
	for(i=0;i<G->vexnum;i++)
	{
		primtree->vertex[i].data=G->vertex[i].data;
		primtree->vertex[i].firstarc=NULL; 
	}
	primtree->vexnum=G->vexnum;
}
ArcNode *makenode(int adjvex,int power)                  /*建立新結點*/ 
{
	ArcNode *newnode=(ArcNode *)malloc(sizeof(ArcNode));
	newnode->nextarc=NULL;
	newnode->adjvex=adjvex;
	newnode->info=power;
	return newnode;
}
void createprimtree(AdjList *G,AdjList *primtree)     /*生成最小生成樹*/ 
{
	int visit[G->vexnum];                         /*visit記錄是否訪問過該頂點*/ 
	int i,j,k;
	int power,adjvex;
	ArcNode *temp=(ArcNode *)malloc(sizeof(ArcNode));
	for(i=0;i<G->vexnum;i++)                         /*visit置為0,表示頂點都還未訪問*/ 
		visit[i]=0;
	visit[0]=1;                                      /*訪問第一個頂點*/ 
	for(i=0;i<G->vexnum;i++)
	{
		power=999;                                   
		for(j=0;j<G->vexnum;j++)
		{
			if(visit[j])                   /*如果該頂點訪問過,尋找和該頂點相鄰的最小權值的未被訪問的頂點*/ 
			{
				temp=G->vertex[j].firstarc;
				while(temp!=NULL)
				{
					if(power>temp->info&&!visit[temp->adjvex])       /*找到和該頂點相鄰的最小權值的未被訪問的頂點更新資訊*/ 
					{
					power=temp->info;
					adjvex=temp->adjvex;
					k=j;                                   /*儲存兩個鄰接的權值最小的頂點資訊*/ 
					}
					temp=temp->nextarc;
				}
			}
		}
		if(!visit[adjvex])                               
		{
			if(primtree->vertex[k].firstarc==NULL)         
			primtree->vertex[k].firstarc=makenode(adjvex,power);            /*將未訪問的頂點接在已訪問的頂點的後面*/ 
			else
			{
				temp=primtree->vertex[k].firstarc;
				while(temp->nextarc!=NULL)
					temp=temp->nextarc;
				temp->nextarc=makenode(adjvex,power);
			}
			visit[adjvex]=1;
		}
	}
	
}
void print(AdjList *primtree)                 /*列印最小生成樹*/ 
{
	ArcNode *p;
	p=(ArcNode *)malloc(sizeof(ArcNode));
	int i;
	for(i=0;i<primtree->vexnum;i++)
	{
		
		p=primtree->vertex[i].firstarc;
		while(p)
		{
			printf("%c—%c(%d)\n",primtree->vertex[i].data,primtree->vertex[p->adjvex].data,p->info);
			p=p->nextarc;
		}
	}
}
int main()
{
	creategraph(G);               /*建立一張圖*/
	initprimtree(G,primtree);      /*初始化最小生成樹*/ 
	createprimtree(G,primtree);     /*生成最小生成樹*/ 
	printf("最小生成樹為:\n"); 
	print(primtree);              /*列印最小生成樹*/ 
	return 0;
}