数据结构—Kruskal最小生成树
原理:参考趣学数据结构
代码:
快速排序:
#pragma once
#define elemType int
typedef struct vER {elemType u;elemType v;int weight;
}VER;
int quickSort(VER a[], int l, int h) {//快速排序int i = l, j = h;VER p = a[l];while (i < j) {while (i<j&&a[j].weight>p.weight) {//从右往左遍历查找比p更小的元素j--;}if (i < j) {a[i++] = a[j];}while (i < j&&a[i].weight <= p.weight) {//从左往右遍历查找比p更大的元素i++;}if (i < j) {a[j--] = a[i];}}a[i] = p;//分界的值,左边小于等于p,右边大于preturn i;
}
void fenZhi(VER a[], int l, int h) {//分治if (l < h) {int mid = quickSort(a, l, h);//以mid为分界线,进行分治,然后递归下去排序fenZhi(a, l, mid - 1);fenZhi(a, mid + 1, h);}
}
Kruskal代码:
#include<stdio.h>
#include<stdlib.h>
#include"quickSort.h"
#define N 100
#define elemType int
//const int MAX_INT = (1 << 31) - 1;
//const int MAX_INT = 0X7fffffff;
#define INF (((unsigned int)(-1)) >> 1)
int visited[N];
typedef struct GraphMatrix {elemType vNode[N][N];int vNum, eNum;
}GraphMatrix;
void initGMaxtix(GraphMatrix &G) {//初始化邻接矩阵printf("输入顶点数和边数\n");scanf_s("%d%d", &G.vNum, &G.eNum);for (int i = 0; i < G.vNum; i++) {//初始化邻接矩阵for (int j = 0; j < G.vNum; j++) {G.vNode[i][j] = INF;}}printf("输入顶点v1到顶点v2和其边的权重\n");for (int i = 0; i < G.eNum; i++) {int v1, v2, weights;scanf_s("%d%d%d", &v1, &v2, &weights);G.vNode[v1][v2] = weights;}
}
void print16(GraphMatrix G) {printf("邻接矩阵如下:\n");for (int i = 0; i < G.vNum; i++) {for (int j = 0; j < G.vNum; j++) {printf("%d ", G.vNode[i][j]);}printf("\n");}
}
bool merge(int u, int v,int vNum) {//把所有是与v顶点同一个集合的 加入到与u顶点的同一个集合int p = visited[u];int q = visited[v];if (p == q) {//同一个集合return false;}for (int i = 0; i < vNum; i++) {if (visited[i] == q) {visited[i] = p;}}return true;
}
void Kruskal(GraphMatrix G, int gouZaoSCTreeENum) {//最小生成树VER a[N];int k = 0;//构造结构体顶点之间权重数组for (int i = 0; i < G.vNum; i++) {for (int j = 0; j < G.vNum; j++) {if (G.vNode[i][j] < INF) {//有边a[k].u = i;a[k].v = j;a[k].weight = G.vNode[i][j];k++;}}}//对边权重进行快速排序fenZhi(a, 0, k - 1);int ans = 0;int n = G.eNum;for (int i = 0; i < gouZaoSCTreeENum; i++) {if (merge(a[i].u, a[i].v, G.vNum)) {ans += a[i].weight;printf("\n%d-----%d有边\n", a[i].u, a[i].v);n--;if (n == 1) {printf("\n最小生成树的边的总长度为%d\n", ans);break;}}}
}
int main() {GraphMatrix G;initGMaxtix(G);print16(G);printf("\n");for (int i = 0; i < G.vNum; i++) {//首先初始化G.vNum个集合visited[i] = i;}printf("Kruskal最小生成树\n");Kruskal(G, G.eNum);printf("\n");system("pause");return 0;
}