Kruskal算法求最小生成树

Kruskal算法求最小生成树(Minimun Cost Spanning Tree简称MST),使用的图的数据结构是边表数组。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 #define MAX_VERTAX_SIZE 20
  5 #define MAX_EAGE_SIZE 50
  6 #define OK 1
  7 #define ERROR 0
  8 
  9 typedef int Status;
 10 typedef char VertaxElemType;
 11 
 12 typedef struct EageNode{
 13     int adjacentVertax;
 14     int weight;
 15     struct EageNode* nextEage;
 16 }EageNode,*EageNodePtr;
 17 typedef struct VertaxNode{
 18     VertaxElemType data;
 19     EageNodePtr firstEage;
 20 }VertaxNode;
 21 typedef struct GraphAL{
 22     VertaxNode vertaxNodeArray[MAX_VERTAX_SIZE];
 23     int vertaxNum;
 24     int eageNum;
 25 }GraphAL;
 26 
 27 typedef struct EageTableNode{
 28     int eageHead;
 29     int eageTail;
 30     int weight;
 31 }EageTableNode;
 32 typedef struct GraphET{
 33     VertaxElemType vertaxArray[MAX_VERTAX_SIZE];
 34     EageTableNode eageTable[MAX_EAGE_SIZE];
 35     int eageNum;
 36     int vertaxNum;
 37 }GraphET;
 38 
 39 int LocateVertax(GraphAL G, VertaxElemType v);
 40 Status CreateGraphAL_UDG_S(GraphAL* G);    
 41 Status FromAdjacencyListToEageTable(GraphAL G, GraphET* G_1);
 42 void PrintEageTable(GraphET G);
 43 void PrintAdjacencyList(GraphAL G);
 44 
 45 int LocateVertax(GraphAL G, VertaxElemType v){
 46     int i;
 47     for( i = 0; i < G.vertaxNum; i++ ){
 48         if( G.vertaxNodeArray[i].data == v )
 49             return i;
 50     }
 51     return -1;
 52 }
 53 //创建无向图,使用邻接矩阵存储
 54 Status CreateGraphAL_UDG_S(GraphAL* G){        //相同的边只存储一次,方便转化为边表结构
 55     int i,index_v,index_w,weight;
 56     VertaxElemType v,w;
 57     EageNodePtr vPtr,wPtr;
 58     printf("  Create UndiGraph with Adjacecy List\n");
 59     printf("please enter the number of VERTAX and EAGE:");
 60     scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));
 61 
 62     printf("ok, please enter the value of vertaxes,Seperated by Space\n   :");
 63     for( i = 0; i < G->vertaxNum; i++ ){
 64         scanf("%c%*c", &(G->vertaxNodeArray[i].data));
 65         G->vertaxNodeArray[i].firstEage = NULL;
 66     }
 67     for( i = 0; i < G->eageNum; i++ ){
 68         printf("ok, please enter the two VERTAX and WEIGHT of EAGE %d\n note: Seperated by Space :", i+1);
 69         scanf("%c %c %d%*c", &v,&w,&weight);
 70         index_v = LocateVertax(*G, v);
 71         index_w = LocateVertax(*G, w);
 72         vPtr = (EageNode*)malloc(sizeof(struct EageNode));
 73         if( !vPtr )
 74             return ERROR;
 75         vPtr->adjacentVertax = index_w;
 76         vPtr->weight = weight;
 77         vPtr->nextEage = G->vertaxNodeArray[index_v].firstEage;
 78         G->vertaxNodeArray[index_v].firstEage = vPtr;
 79         /*
 80         wPtr = (EageNode*)malloc(sizeof(struct EageNode));
 81         if( !wPtr )
 82             return ERROR;
 83         wPtr->adjacentVertax = index_v;
 84         wPtr->weight = weight;
 85         wPtr->nextEage = G->vertaxNodeArray[index_w].firstEage;
 86         G->vertaxNodeArray[index_w].firstEage = wPtr;
 87         */
 88     }
 89     //PrintAdjacencyList(*G);
 90     return OK;
 91 }
 92 //将图的邻接表表示转化为图的边表表示,kruskal算法将要使用这种结构
 93 Status FromAdjacencyListToEageTable(GraphAL G, GraphET* G_1){
 94     int i,j;
 95     EageNodePtr p;
 96     int counterOfEage = 0;
 97     G_1->eageNum = G.eageNum;
 98     G_1->vertaxNum = G.vertaxNum;
 99     for( i = 0; i < G.vertaxNum; i++ )
100         G_1->vertaxArray[i] = G.vertaxNodeArray[i].data;
101     for( i = 0; i < G.vertaxNum; i++ ){
102         p = G.vertaxNodeArray[i].firstEage;
103         while( p ){
104             G_1->eageTable[counterOfEage].eageHead = i;
105             G_1->eageTable[counterOfEage].eageTail = p->adjacentVertax;
106             G_1->eageTable[counterOfEage].weight = p->weight;
107             counterOfEage++;
108             p = p->nextEage;
109         }
110     }
111     //PrintEageTable(*G_1);
112     //排序,按权值从小到大
113     EageTableNode temp;
114     for( i = 0; i < G_1->eageNum - 1; i++ ){
115         for( j = i; j < G_1->eageNum; j++ ){
116             if( G_1->eageTable[i].weight > G_1->eageTable[j].weight ){
117                 temp.eageHead = G_1->eageTable[i].eageHead;
118                 temp.eageTail = G_1->eageTable[i].eageTail;
119                 temp.weight = G_1->eageTable[i].weight;
120                 G_1->eageTable[i].eageHead = G_1->eageTable[j].eageHead;
121                 G_1->eageTable[i].eageTail = G_1->eageTable[j].eageTail;
122                 G_1->eageTable[i].weight = G_1->eageTable[j].weight;
123                 G_1->eageTable[j].eageHead = temp.eageHead;
124                 G_1->eageTable[j].eageTail = temp.eageTail;
125                 G_1->eageTable[j].weight = temp.weight;
126             }
127         }
128     }
129     if( counterOfEage == G_1->eageNum ){
130         return OK;
131     }
132     else{
133         return ERROR;
134     }
135 }
136 void PrintEageTable(GraphET G){
137     int i;
138     printf("\nPrint Eage Table\n");
139     printf("--------------------------------------------------\n");
140     printf("| order | startVertax  | endVertax  | eageWeight |\n");
141     for( i = 0; i < G.eageNum; i++ ){
142         printf("|------------------------------------------------|\n");
143         printf("|   %d   |      %d       |      %d     |     %d      |\n", i+1, G.eageTable[i].eageHead, G.eageTable[i].eageTail, G.eageTable[i].weight);
144     }
145     printf("--------------------------------------------------\n");
146 }
147 void PrintAdjacencyList(GraphAL G){
148     int i;
149     EageNodePtr p;
150     for( i = 0; i < G.vertaxNum; i++ ){
151         printf(" %d %c : ",i+1, G.vertaxNodeArray[i].data);
152         p = G.vertaxNodeArray[i].firstEage;    
153         while( p != NULL ){
154             printf("--->%d weight(%d)", p->adjacentVertax+1,p->weight);
155             p = p->nextEage;
156         }
157         printf("\n");
158     }
159 }
160 
161 int getindex(int* array, int index){
162     while( array[index] != 0 ){
163         index = array[index];
164     }
165     return index;
166 }
167 Status Kruskal(GraphET G){
168     int i;
169     int MSTed[MAX_VERTAX_SIZE];    //这个数组是Kruskal算法的关键
170     int v,w;
171     for( i = 0; i < G.vertaxNum; i++ )
172         MSTed[i] = 0;
173     printf("MST(Minimum Cost Spanning Trss) by Kruskal\n");
174     for( i = 0; i < G.eageNum; i++ ){
175         v = getindex(MSTed, G.eageTable[i].eageHead);
176         w = getindex(MSTed, G.eageTable[i].eageTail);
177         if( v != w ){
178             printf("(%c, %c) weight(%d)\n", G.vertaxArray[G.eageTable[i].eageHead], G.vertaxArray[G.eageTable[i].eageTail], G.eageTable[i].weight);
179             MSTed[v] = w;
180         }
181     }
182     return OK;
183 }
184 int main(){
185     GraphAL G;
186     CreateGraphAL_UDG_S(&G);
187     GraphET G_1;
188     FromAdjacencyListToEageTable(G, &G_1);
189     PrintEageTable(G_1);
190     Kruskal(G_1);
191     return OK;
192 }

posted @ 2016-03-13 14:53  robin_X  阅读(1835)  评论(0编辑  收藏  举报