码迷,mamicode.com
首页 > 编程语言 > 详细

克鲁斯卡尔(Kruskal)算法

时间:2015-03-03 18:34:20      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:

                                                技术分享

  1 # include <stdio.h>
  2 
  3 # define MAX_VERTEXES 100//最大顶点数
  4 # define MAXEDGE 20//边集数组最大值
  5 # define INFINITY 65535//代表不可能的数(无穷大)
  6 
  7 typedef struct
  8 {//图 结构体定义
  9     int arc[MAX_VERTEXES][MAX_VERTEXES];//二位数组 矩阵
 10     int numVertexes, numEdges;//当前图中的顶点数和边数
 11     
 12 }MGraph;
 13 
 14 typedef struct
 15 {//边集数组 结构体定义
 16     int begin;
 17     int end;
 18     int weight;
 19 
 20 }Edge;
 21 
 22 void CreateMGraph (MGraph *G)
 23 {//创建
 24      int i, j;
 25      //下面是已经输入好的
 26      G->numVertexes = 9;
 27      G->numEdges = 15;
 28 
 29      for (i=0; i<G->numVertexes; i++)
 30          for (j=0; j<G->numVertexes; j++)
 31              if (i == j)
 32                  G->arc[i][j] = 0;
 33              else
 34                  G->arc[i][j] = G->arc[j][i] = INFINITY;
 35 
 36     G->arc[0][1]=10;
 37     G->arc[0][5]=11; 
 38     G->arc[1][2]=18; 
 39     G->arc[1][8]=12; 
 40     G->arc[1][6]=16; 
 41     G->arc[2][8]=8; 
 42     G->arc[2][3]=22; 
 43     G->arc[3][8]=21; 
 44     G->arc[3][6]=24; 
 45     G->arc[3][7]=16;
 46     G->arc[3][4]=20;
 47     G->arc[4][7]=7; 
 48     G->arc[4][5]=26; 
 49     G->arc[5][6]=17; 
 50     G->arc[6][7]=19; 
 51 
 52     for (i=0; i<G->numVertexes; i++)
 53         for (j=i+1; j<G->numVertexes; j++)//矩阵的上三角,然后对称矩阵的下三角
 54             G->arc[j][i]  = G->arc[i][j];//对称
 55 }
 56 
 57 void swapn (Edge *edges, int i, int j)
 58 {//交换权值
 59     int temp;
 60 
 61     //起始
 62     temp = edges[i].begin;
 63     edges[i].begin = edges[j].begin;
 64     edges[j].begin = temp;
 65 
 66     //结束
 67     temp = edges[i].end;
 68     edges[i].end = edges[j].end;
 69     edges[j].end = temp;
 70 
 71     //权值
 72     temp = edges[i].weight;
 73     edges[i].weight = edges[j].weight;
 74     edges[j].weight = temp;
 75 
 76     return ;
 77 }
 78 
 79 void sort (Edge edges[], MGraph *G)
 80 {//对权值进行排序
 81     int i, j;
 82     for (i=0; i<G->numEdges; i++)
 83         for (j=i+1; j<G->numEdges; j++)//对存入有效边(两端点的权值)进行冒泡排序
 84             if (edges[i].weight > edges[j].weight)
 85                 swapn (edges, i, j);//交换权值
 86 
 87     printf ("排序过后:\n");
 88     for (i=0; i<G->numEdges; i++)
 89         printf ("边:(%d,%d) 权值:%d\n", edges[i].begin, edges[i].end, edges[i].weight);
 90 
 91     return ;
 92 }
 93 
 94 int Find (int *parent, int f)//
 95 {// 查找连线顶点的尾部下标
 96 //走过的路都有记录,如果走已经走过的路的话,那么返回的值(n=m);
 97     while (parent[f] > 0)
 98         f = parent[f];
 99     return f;
100 }
101 
102 void MiniSpanTree_Kruskal (MGraph G)
103 {//克鲁斯卡尔算法
104     int i, j, n, m;
105     int k = 0;
106     int parent[MAX_VERTEXES];//定义一维数组判断是否形成环路
107     Edge edges[MAXEDGE];//定义边集数组
108 
109     for (i=0; i<G.numVertexes; i++)//存储有效的边(两个端点和权值)
110         for (j=i+1; j<G.numVertexes; j++)//矩阵上三角进行比较,因为对称,所以比较一半更节约时间
111             if (G.arc[i][j] < INFINITY)
112             {
113                 edges[k].begin = i;
114                 edges[k].end = j;
115                 edges[k ++].weight = G.arc[i][j];
116             }
117     sort(edges, &G);//排序
118 
119     for (i=0; i<G.numVertexes; i++)
120         parent[i] = 0;
121 
122     printf ("\n打印最小生成树:\n");
123     for (i=0; i<G.numEdges; i++)
124     {
125         n = Find (parent, edges[i].begin);//
126         m = Find (parent, edges[i].end);//
127         if (n != m)
128         {
129             parent[n] = m;
130             printf ("边(%d,%d) 权值:%d\n", edges[i].begin, edges[i].end, edges[i].weight);
131         }
132     }
133 }
134 
135 int main (void)
136 
137 {
138     MGraph G;
139     CreateMGraph (&G);//创建
140     MiniSpanTree_Kruskal (G);//克鲁斯卡尔 算法
141 
142     return 0;
143 }
144 
145 /*
146 在vc++6.0运行结果:
147 
148     排序过后:
149     边:(4,7) 权值:7
150     边:(2,8) 权值:8
151     边:(0,1) 权值:10
152     边:(0,5) 权值:11
153     边:(1,8) 权值:12
154     边:(3,7) 权值:16
155     边:(1,6) 权值:16
156     边:(5,6) 权值:17
157     边:(1,2) 权值:18
158     边:(6,7) 权值:19
159     边:(3,4) 权值:20
160     边:(3,8) 权值:21
161     边:(2,3) 权值:22
162     边:(3,6) 权值:24
163     边:(4,5) 权值:26
164 
165     打印最小生成树:
166     边(4,7) 权值:7
167     边(2,8) 权值:8
168     边(0,1) 权值:10
169     边(0,5) 权值:11
170     边(1,8) 权值:12
171     边(3,7) 权值:16
172     边(1,6) 权值:16
173     边(6,7) 权值:19
174     Press any key to continue
175 */

 

克鲁斯卡尔(Kruskal)算法

标签:

原文地址:http://www.cnblogs.com/bebug/p/4311462.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!