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 }