/* kruskal 算法:每次选择最短的一条边加入集合,直至所有顶点被包含,而且会用到并查集*/#include<stdio.h>#include <stdlib.h>#define MAXSIZE 100#define TYPE inttypedef struct EdgeNode {//边表结点 int index;//该边所指向的顶点的位置 int weight;//权值 EdgeNode *next;//下一个邻接边}EdgeNode;typedef struct VertexNode {//顶点表节点 char info;//顶点信息 EdgeNode *firstEdge;//指向第一条依附该顶点的边的指针}VertexNode, Adjlist[MAXSIZE];typedef struct { Adjlist adjlist;//顶点数组 int numE, numV;//边数、顶点数}ALGraph;struct Tree { char data; struct Tree *lchild, *rchild;};void outPut(ALGraph *G, int **weights) {//输出最小生成树 for (int i = 0; i < G->numV; i++) { for (int j = i; j < G->numV; j++) { if (weights[i][j] != 0) { printf("%c->%c(%d)\n", G->adjlist[i].info, G->adjlist[j].info, weights[i][j]); } } }}int findAnster(int *fa, int i) { if (fa[i] == i)return i;//找到返回 else { fa[i] = findAnster(fa, fa[i]);//进行路径压缩,即将i处 return fa[i];//未找到继续 }}void unionn(int *fa, int i, int j) { int i_a = findAnster(fa, i); int j_a = findAnster(fa, j); fa[i_a] = j_a;//i的祖先指向j的祖先}void kruskal(ALGraph *G) { int **weights = (int **)malloc(sizeof(int *)*G->numV);//两点间的权值数据 int *fa = (int *)malloc(sizeof(int)*G->numV);//并查集数组 for (int i = 0; i < G->numV; i++) { fa[i] = i;//最开始将每个节点的祖先设置为自己 } for (int i = 0; i < G->numV; i++) { weights[i] = (int *)malloc(sizeof(int *)*G->numV); } for (int i = 0; i < G->numV; i++) { for (int j = 0; j < G->numV; j++) { weights[i][j] = 0;//初始化该二位数组 } } int edges = 0; while (edges < G->numV - 1) { int weight = 32767; int start, end; for (int i = 0; i < G->numV; i++) {//遍历每一个顶点的所有边 for (EdgeNode *p = G->adjlist[i].firstEdge; p; p = p->next) { //寻找最短边 if (p->weight < weight && findAnster(fa, i) != findAnster(fa, p->index)) { weight = p->weight; start = i; end = p->index; } } } unionn(fa, start, end); weights[start][end] = weight; weights[end][start] = weight; edges++; } outPut(G, weights);}int main() { ALGraph *G = (ALGraph *)malloc(sizeof(ALGraph *)); void createGraphInFile(ALGraph *); void dispGraph(ALGraph *); createGraphInFile(G);//创建图 dispGraph(G); kruskal(G); return 0;}