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 */
时间: 2024-11-08 00:43:39