最小生成樹(鄰接表寫法)
阿新 • • 發佈:2019-01-24
#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; }