克鲁斯卡尔算法--最小生成树的算法
关键点:辅助数组:用于保存连通分量,来判断边是否连通
//克鲁斯卡尔算法
#include <stdio.h>
#include <stdlib.h>
#define MAX 32767
typedef struct Graph {
char* vexs;
int** arcs;
int vexNum;
int arcNum;
}Graph;
typedef struct Edge {
int start; //边的起点
int end; //边的终点
int weight; //边的权值
}Edge;
Edge* initEdge(Graph* G) {
int index = 0;
Edge* edge = (Edge*)malloc(sizeof(Edge) * G -> arcNum);
//此算法的特点是对自己顶点之前的权值不予统计并且对MAX权值也不统计
//目的是保证图不是连通的
for (int i = 0; i < G -> vexNum; i++) {
for (int j = i + 1; j < G -> vexNum; j++) {
if (G -> arcs[i][j] != MAX) {
edge[index].start = i;
edge[index].end = j;
edge[index].weight = G -> arcs[i][j];
index++;
}
}
}
return edge;
}
//对边的权值进行排序
void sortEdge(Edge* edge, Graph* G) {
Edge temp;
for (int i = 0; i < G -> arcNum - 1; i++) {
for (int j = 0; j < G -> arcNum - i - 1; j++) {
if (edge[j].weight > edge[j + 1].weight) {
temp = edge[j];
edge[j] = edge[j + 1];
edge[j + 1] = temp;
}
}
}
}
void kruskal(Graph* G) {
int* connected = (int*)malloc(sizeof(int) * G -> vexNum);
for (int i = 0 ; i < G -> vexNum; i++) {
connected[i] = i; //对辅助数组进行初始化,原始时自己等于自己
}
Edge* edge = initEdge(G);
sortEdge(edge, G);
for (int i = 0; i < G -> arcNum; i++) {
int start = connected[edge[i].start];
int end = connected[edge[i].end];
if (start != end) { //不等的话说明未连通
printf("v%c --> v%c weight = %d\n", G -> vexs[edge[i].start], G -> vexs[edge[i].end], edge[i].weight);
for (int j = 0; j < G -> vexNum; j++) {
if (connected[j] == end) { //如果有点的连通分量跟终点相等
connected[j] = start; //就让他等于起点的连通分量
}
}
}
}
}
Graph* initGraph(int vexNum) {
Graph* G = (Graph*)malloc(sizeof(Graph));
G -> vexs = (char*)malloc(sizeof(char) * vexNum);
G -> arcs = (int**)malloc(sizeof(int*) * vexNum);
for (int i = 0 ; i < vexNum; i++) {
G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);
}
G -> vexNum = vexNum;
G -> arcNum = 0;
return G;
}
void createGraph(Graph* G, char* vexs, int* arcs) {
for (int i = 0 ; i < G -> vexNum; i++) {
G -> vexs[i] = vexs[i];
for (int j = 0; j < G -> vexNum; j++) {
G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);
if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)
G -> arcNum ++;
}
}
G -> arcNum /= 2;
}
void DFS(Graph* G, int* visited, int index) {
printf("%c\t", G -> vexs[index]);
visited[index] = 1;
for (int i = 0; i < G ->vexNum; i++) {
if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) {
DFS(G, visited, i);
}
}
}
int main() {
Graph* G = initGraph(7);
int* visited = (int*)malloc(sizeof(int) * G -> vexNum);
for (int i = 0; i < G -> vexNum; i++)
visited[i] = 0;
int arcs[7][7] = {
0,6,6,1,MAX,MAX,MAX,
6,0,MAX,4,5,MAX,MAX,
6,MAX,0,6,MAX,MAX,2,
1,4,6,0,5,5,3,
MAX,5,MAX,5,0,6,MAX,
MAX,MAX,MAX,5,6,0,6,
MAX,MAX,2,3,MAX,6,0
};
createGraph(G, "1234567", (int*)arcs);
DFS(G, visited, 0);
printf("\n");
kruskal(G);
return 0;
}