设计,编程,调试,测试过程
最小生成树有两种算法:
一种是Prim 算法,它是一种最小生成树算法,它将图作为输入并找到该图边的子集,形成包含每个顶点的树,在可以从图形形成的所有树中找到具有最小的权重总和。
它属于一类称为贪婪算法的算法,它们找到局部最优,希望找到全局最优。从一个顶点开始,不断添加权重最低的边缘,直到达到目标。
实现 Prim 算法的步骤如下:
1. 使用随机选择的顶点初始化最小生成树。
2. 找到将树连接到新顶点的所有边,找到最小值并将其添加到树中。
3. 继续重复步骤 2,直到获得最小生成树。
C++代码:
#include <cstring>
#include <iostream>
using namespace std;
#define INF 9999999
#define V 5
int G[V][V] = { //用矩阵存储图
{0, 9, 75, 0, 58},
{9, 0, 95, 19, 42},
{75, 95, 0, 51, 66},
{0, 19, 51, 0, 31},
{58, 42, 66, 31, 0}};
int main()
{
int no_edge; // 边的数量
int selected[V];
memset(selected, false, sizeof(selected));
no_edge = 0;
selected[0] = true;
int x; // 行
int y; // 列
cout << "Edge"
<< " : "
<< "Weight";
cout << endl;
while (no_edge < V - 1)
{
int min = INF;
x = 0;
y = 0;
for (int i = 0; i < V; i++)
{
if (selected[i])
{
for (int j = 0; j < V; j++)
{
if (!selected[j] && G[i][j])
{
if (min > G[i][j])
{
min = G[i][j];
x = i;
y = j;
}
}
}
}
}
cout << x << " - " << y << " : " << G[x][y];
cout << endl;
selected[y] = true;
no_edge++;
}
return 0;
}
运行结果截图:
另一种是Kruskal算法,它同样属于贪婪算法。有所不同的是,Kruskal 算法是基于边的算法,它每次选取最小费用的边进行连接,而不影响之前形成的最小生成树。Prim 算法是基于点的算法,它每次从最小生成树外的点中选取与树最近且代价最小的点进行连接。
实现 Kruskal 算法的步骤如下: