Kruskal algorithm understanding:
For the minimum path of n vertices, the spanning tree has n-1 paths
First, arrange the vertices from small to large by weight
Then choose the weights from the smallest
Set up a parent array for selection,
which means that the parent will change every time
But for a path, if the ending corresponds to the value of the same position of the parent, it means that the vertex is taken twice.
Define adjacency matrix and edge set array
#include<iostream>
#include <iomanip>
using namespace std;
typedef char Vertextype;//顶点类型
typedef int Edgetype;//边缘权值
typedef int Status;
#define MAXVER 9//最大顶点数
#define INF 65535//代表无穷
#define NULL 0
//定义图——邻接矩阵
typedef struct Graph
{
Vertextype Ver[MAXVER];
Edgetype Arc[MAXVER][MAXVER];
int NumVer, NumEdg;
}MGraph;
//定义边集数组Edge
typedef struct EdgeNode{
int begin;
int end;
int weight;
}EdgeNode, *Edge;//这个数组一定要固定吗 开始我这里是写的固定数组 改成这样后面加上一个new即可变成动态数组
Status Find(int *parent, int f);
Generate graph
//生成图——邻接矩阵
Status CreatGraph(MGraph &G)
{
int i, j, w;
cout << "Please enter the number of verticesof the graph : " << endl;
cin >> G.NumVer;
cout << "Please enter the number of edges the graph : " << endl;
cin >> G.NumEdg;
cout << "Please enter the name of vex : " << endl;
for (i = 0; i < G.NumVer; i++){
//cout << "Please enter the NO." << i + 1 << "%d name of vex : " << endl;
cin >> G.Ver[i];
}
cout << "Diagonal infinity ..." << endl;
for (i = 0; i < G.NumVer; i++)
for (j = 0; j < G.NumVer; j++)
{
G.Arc[i][j] = INF;//简单图 不循环
//cout << G.arc[i][j] << endl;//不理解为啥是1
}
cout << "...Diagonal infinity" << endl;
for (int k = 0; k < G.NumEdg; k++){
//因为具体哪条边存在不一定 所以选择性输入边
cout << "Enter the subscripts and weights from vertex vi to vertex vj : " << endl;
cin >> i >> j >> w;
/*cout << "Please enter the subscript j of the edge : " << endl;
cin >> j;
cout << "Please enter the weight from vertex "<<i<<" to vertex "<<j<<" : " << endl;
cin >> w;*/
G.Arc[i][j] = w;
G.Arc[j][i] = G.Arc[i][j];//无向图 边的信息 是对称的 //有向图的话 无需设置
}
return 0;
}
//Convert the adjacency matrix into an edge set array
Pay attention when the adjacency matrix has symmetry and the main diagonal elements do not exist traversal assignment
Status GraphToEdge(MGraph &G, Edge *edges)
{
EdgeNode *t;
int i, j,k=0;
//观察邻接矩阵的结构 主对角线不存在 只遍历一半即可
for (i = 0; i < G.NumVer; i++)
for (j = i+1; j < G.NumVer; j++){
if (G.Arc[i][j] != INF){
//权值存在
edges[k] = new EdgeNode;
edges[k]->begin = i;
edges[k]->end = j;
edges[k]->weight = G.Arc[i][j];
k++;
}
}
//cout << k << endl << endl;
//冒泡排序
for (i = 0; i < G.NumEdg - 1; i++)
for (j = 0; j < G.NumEdg - i - 1;j++)
if (edges[j]->weight > edges[j + 1]->weight){
t = edges[j];
edges[j] = edges[j+1];
edges[j + 1] = t;
}
/*for (i = 0; i < G.NumEdg; i++){
cout << edges[i].weight << endl;
}*/
return 0;
}
Kruskal algorithm
A better understanding of the parent’s hand animation
Status MinSpanTree(MGraph &G,Edge *edges)
{
int i, n, m;
int parent[MAXVER];
for (i = 0; i < G.NumVer; i++)
parent[i] = 0;
for (i = 0; i < G.NumEdg; i++)
{
n = Find(parent, edges[i]->begin);//选择首尾下标
m = Find(parent,edges[i]->end);
if (m != n)//判断是否循环 这里画图更容易理解
{
parent[n] = m;
cout << edges[i]->begin << "____" << edges[i]->end << "____" << edges[i]->weight << endl;
}
}
return 0;
}
Status Find(int *parent, int f)
{
while (parent[f]>0)
{
f = parent[f];
}
return f;
}
int main()
{
MGraph G;
Edge *edges=(Edge *)malloc(sizeof(EdgeNode));
CreatGraph(G);
GraphToEdge(G,edges);
MinSpanTree(G,edges);
system("pause");
return 0;
}