prim算法适用条件_最小生成树之Prim算法和Kruskal算法

1 /*

2 * kruskal.c3 *4 * Created on: 2017年5月15日5 * Author: ygh6 */

7

8 #include

9 #include

10

11 #define MAX_VERTEX_NUM 10001 /*define the max number of the vertex*/

12 #define INFINITY 65535 /*define double byte no negitive integer max number is 65535*/

13 #define ERROR -1

14

15 typedef int vertex; /*define the data type of the vertex*/

16 typedef int weightType; /*define the data type of the weight*/

17 typedef char dataType; /*define the data type of the vertex value*/

18

19 /*define the data structure of the Edge*/

20 typedef struct eNode *ptrToENode;21 typedef structeNode {22 vertex v1, v2; /*two vertex between the edge */

23 weightType weight; /*the value of the edge's weight*/

24 };25 typedef ptrToENode edge;26

27 /*==================A adjacent link to describe a graph=========================================*/

28 /*define the data structure adjacent table node*/

29 typedef struct adjNode *ptrToAdjNode;30 typedef structadjNode {31 vertex adjVerx; /*the index of the vertex*/

32 weightType weight; /*the value of the weight*/

33 ptrToAdjNode next; /*the point to point the next node*/

34 };35

36 /*define the data structure of the adjacent head*/

37 typedef struct vNode *ptrToVNode;38 typedef structvNode {39 ptrToAdjNode head; /*the point to point the adjacent table node*/

40 dataType data; /*the space to store the name of the vertex,but some time the vertex has no names*/

41 } adjList[MAX_VERTEX_NUM];42

43 /*define the data structure of graph*/

44 typedef struct gLNode *ptrTogLNode;45 typedef structgLNode {46 int vertex_number; /*the number of the vertex*/

47 int edge_nunber; /*the number of the edge*/

48 adjList g; /*adjacent table*/

49 };50 typedef ptrTogLNode adjacentTableGraph; /*a graph show by adjacent table*/

51

52 /*

53 create a graph given the vertex number.54 @param vertexNum The verter number of the graph55 @return a graph with vertex but no any egdgs56 */

57 adjacentTableGraph createLGraph(intvertexNum) {58 adjacentTableGraph graph;59

60 vertex v;61 graph = (adjacentTableGraph) malloc(sizeof(structgLNode));62 graph->vertex_number =vertexNum;63 graph->edge_nunber = 0;64 /*initialize the adjacent table*/

65 for (v = 0; v < graph->vertex_number; v++) {66 graph->g[v].head =NULL;67 }68 returngraph;69 }70

71 /*

72 insert a edge to graph.We will distinct oriented graph and undirected graph73 The e->v1 and e->v2 are the vertexs' indexs in the adjacent table74 @param graph The graph you want to insert edge75 @param e The edge you want to insert the graph76 @param isOriented Whether the graph is oriented graph.If the graph is oriented77 we will set adjacent table graph[v1]->head=v2 and set graph[v1].head=v278 otherwise we only set graph[v1].head=v279 */

80 void insertEdgeToLink(adjacentTableGraph graph, edge e, intisOriented) {81 /*build node*/

82 ptrToAdjNode newNode;83 newNode = (ptrToAdjNode) malloc(sizeof(structadjNode));84 newNode->adjVerx = e->v2;85 newNode->weight = e->weight;86 newNode->next = graph->g[e->v1].head;87 graph->g[e->v1].head =newNode;88 /*if the graph is directed graph*/

89 if (!isOriented) {90 newNode = (ptrToAdjNode) malloc(sizeof(structadjNode));91 newNode->adjVerx = e->v1;92 newNode->weight = e->weight;93 newNode->next = graph->g[e->v2].head;94 graph->g[e->v2].head =newNode;95 }96 }97

98 /*

99 build a graph stored by adjacent table100 */

101 adjacentTableGraph buildLGraph(intisOrdered) {102 adjacentTableGraph graph;103 edge e;104 vertex i;105 intvertex_num;106

107 scanf("%d", &vertex_num);108 graph =createLGraph(vertex_num);109 scanf("%d", &(graph->edge_nunber));110 if (graph->edge_nunber) {111 e = (edge) malloc(sizeof(structeNode));112 for (i = 0; i < graph->edge_nunber; i++) {113 scanf("%d %d %d", &e->v1, &e->v2, &e->weight);114 e->v1--;115 e->v2--;116 insertEdgeToLink(graph, e, isOrdered);117 }118 }119

120 returngraph;121 }122

123 /*----------------------define collection and some operator of graph's nodes-----------------------------*/

124

125 /*

126 * The element of collection127 */

128 typedef vertex elementType;129

130 /*

131 * The index of root element,we use it as the collection name132 */

133 typedef vertex setName;134

135 /*

136 * A array to store the collection,we set the137 * first index is 0138 */

139 typedef elementType setType[MAX_VERTEX_NUM];140

141 /*

142 * Initialize collection143 * @param A elementType array to store the collections,maybe144 * many collection will be stored in this array145 * @param n The length of the collection146 */

147 void initializeVSet(setType s, intn) {148 elementType x;149 for (x = 0; x < n; x++) {150 s[x] = -1;151 }152 }153

154 /*

155 * Union two collections which is showed by root element.We will union smaller collection156 * to greater collection and we will update the quantity for greater collection157 * @param s A elementType array to store the collections,maybe158 * many collection will be stored in this array159 * @param root1 The root element of the first collection160 * @param root2 The root element of the second collection161 */

162 voidunionCollection(setType s, setName root1, setName root2) {163 /*

164 * If root2's quantity greater than root1165 */

166 if (s[root2]

175 /*

176 * Find the element in which collection and use the root element177 * to represent this collection and return it.In this method,we will compress path178 * @param s A elementType array to store the collections,maybe179 * many collection will be stored in this array180 * @param x The element we find which collection it in.181 */

182 setName find(setType s, elementType x) {183 if (s[x] < 0) {184 returnx;185 } else{186 /*

187 *compress path188 */

189 return s[x] =find(s, s[x]);190 }191 }192

193 /*

194 * Check v1 and v1 whether is belong to a same collection. If not union these195 * two collection,otherwise do nothing.196 * @param vSet A elementType array to store the collections,maybe197 * many collection will be stored in this array198 * @param v1 The index of node in the graph,also the element is the collection.199 * @param v2 The index of node in the graph,also the element is the collection.200 * @return If the two element is belong same collection,union them and return 1201 * else do nothing and return 0;202 */

203 intcheckCircle(setType vSet, vertex v1, vertex v2) {204 setName root1 =find(vSet, v1);205 setName root2 =find(vSet, v2);206 if (root1 ==root2) {207 return 0;208 } else{209 unionCollection(vSet, root1, root2);210 return 1;211 }212 }213

214 /*-------------define the minimal heap of edge-------------------*/

215

216 /*

217 * Update the tree whose root element index is p into minimal heap,we use the edgs's218 * weight as the to construct the minimal heap.219 *220 * @param eset A array of edge to store the heap,because the edge is point variable221 * So the eSet is a edge type array,you can compare it with int* arr222 * @param The index of the root element.223 * @param n The length of the heap,the max index is n-1 in this case. And224 * this heap index is start from zero.225 */

226 void percDowm(edge eSet, int p, intn) {227 intparent, child;228 structeNode x;229

230 x =eSet[p];231 for (parent = p; (parent * 2 + 1) < n; parent =child) {232 /*

233 * Because the first index if from zero,so the left child234 * is parent*2+1235 */

236 child = parent * 2 + 1;237 /*

238 * Find smaller weigh between the left child and right child239 */

240 if ((child != n - 1) && eSet[child].weight > eSet[child + 1].weight) {241 child++;242 }243 if (x.weight <=eSet[child].weight) {244 break;245 } else{246 eSet[parent] =eSet[child];247 }248 }249 eSet[parent] =x;250 }251

252 /*

253 * Initialize eSet heap and update it to be the minimal heap254 * @param graph A graph which is stored by adjacent list255 * @param eSet A array of the edge as the minimal heap256 */

257 voidinitializeESet(adjacentTableGraph graph, edge eSet) {258 vertex v;259 ptrToAdjNode w;260 int counter = 0;261 for (v = 0; v < graph->vertex_number; v++) {262 for (w = graph->g[v].head; w; w = w->next) {263 /*

264 * expect for put same edge to it,we only265 * put to it.266 */

267 if (v < w->adjVerx) {268 eSet[counter].v1 =v;269 eSet[counter].v2 = w->adjVerx;270 eSet[counter].weight = w->weight;271 counter++;272 }273

274 }275 }276 /*

277 * Initialize the minimal heap278 */

279 for (counter = graph->edge_nunber / 2; counter >= 0; counter--) {280 percDowm(eSet, counter, graph->edge_nunber);281 }282 }283

284 /*

285 * Get minimal edge from the minimal weight heap286 * @param eset A array of edge to store the heap,because the edge is point variable287 * So the eSet is a edge type array,you can compare it with int* arr288 * @param The current size of the minimal heap289 * @return The index of the minimal edge in this heap(array)290 */

291 int getEdge(edge eSet, intcurrentSize) {292 if (currentSize == 0) {293 return currentSize - 1;294 }295 struct eNode temp = eSet[currentSize - 1];296 eSet[currentSize - 1] = eSet[0];297 eSet[0] =temp;298 percDowm(eSet, 0, currentSize - 1);299 return currentSize - 1;300 }301

302 /*

303 * Implement the kruskal algorithms to find the minimal created tree304 * Algorithms thought:we choose the minimal edge from graph but don't305 * construct a circle each time. Until we choose the V-1 edges. The V306 * is equal with the quantity of the graph's vertex307 * In this program,we will use a counter to record the quantity of edges308 * At last of this method,if we check the quantity of the edge is less than309 * V-1, it indicates the graph is not collected,so -1 will be return,otherwise we will return310 * the minimal created tree total weight.311 * @param graph A graph which is stored by adjacent list312 * @param mst A A graph which is stored by adjacent list to store the minimal created tree313 * @return If the graph is collected,the weight of the minimal created tree314 * will be return, otherwise return -1315 */

316 intkruskal(adjacentTableGraph graph, adjacentTableGraph mst) {317 /*

318 * totalWeight is to record the total weight319 * of the minimal created tree320 */

321 weightType totalWeight;322 /*

323 * eCounter is to record the quantity of edges which has been324 * insert the mst325 *326 * nextEdge is to record the next minimal edge in the minimal heap327 */

328 inteCounter, nextEdge;329

330 /*

331 *A set of the vertex to store the vertex and implement332 *some operation such as union find and so on333 */

334 setType vSet;335

336 /*

337 * A array of edge to as the minimal heap to store the egdes338 */

339 edge eSet;340

341 /*

342 * Initialize some variables343 */

344 initializeVSet(vSet, graph->vertex_number);345 eSet = (edge) malloc((sizeof(struct eNode)) * (graph->edge_nunber));346 initializeESet(graph, eSet);347 //mst = createLGraph(graph->vertex_number);

348 totalWeight = 0;349 eCounter = 0;350 nextEdge = graph->edge_nunber;351 while (eCounter < graph->vertex_number - 1) {352 nextEdge =getEdge(eSet, nextEdge);353 if (nextEdge < 0) {354 break;355 }356 /*

357 * Check whether a circle between two vertex358 */

359 if(checkCircle(vSet, eSet[nextEdge].v1, eSet[nextEdge].v2)) {360 insertEdgeToLink(mst, eSet + nextEdge, 0);361 totalWeight +=eSet[nextEdge].weight;362 eCounter++;363 }364 }365 if (eCounter < graph->vertex_number - 1) {366 totalWeight = -1;367 }368 returntotalWeight;369 }370

371 /*========Use DFS to print the result of the minimal created tree==========*/

372 /*

373 * A method to access graph374 */

375 voidvisit(adjacentTableGraph graph, vertex v) {376 printf("%d", v);377 }378

379 /*

380 Depth first search a graph381 @param graph The graph need to search382 @param startPoint The fisrt point we start search the graph383 @paran int *visited The array we use to tag the vertex we has accessed.384 */

385 void DFS(adjacentTableGraph graph, vertex startPoint, int *visited) {386 ptrToAdjNode p;387 visit(graph, startPoint);388 p = graph->g[3].head;389 visited[startPoint] = 1;390 for (p = graph->g[startPoint].head; p; p = p->next) {391 if (visited[p->adjVerx] == 0) {392 DFS(graph, p->adjVerx, visited);393 }394 }395 }396

397 /*

398 * Initialize a visited array that make them all to zero399 */

400 void initVisited(int length, int *visited) {401 inti;402 for (i = 0; i < length; i++) {403 visited[i] = 0;404 }405 }406

407 intmain() {408 adjacentTableGraph graph = buildLGraph(0);409 adjacentTableGraph mst = createLGraph(graph->vertex_number);410 vertex visited[graph->vertex_number];411 weightType totalWeight =kruskal(graph, mst);412 printf("%d\n", totalWeight);413 /*initVisited(graph->vertex_number, visited);414 DFS(mst, 0, visited);*/

415 return 0;416 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值