最小生成树-Prim算法和Kruskal算法
原文链接:https://blog.csdn.net/lsgo_myp/article/details/91435589
Prim算法
加点法
1.算法简单描述
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp1
{
class Program
{
//结点初始状态
static int N = -1;
//结点已加入状态
static int Y = 1;
static void Main(string[] args)
{
//起始点 顶点以0开始 A顶点为0,B为1
int start = 3;
//无向图邻接矩阵
int[,] map = new int[7, 7] {
{0,7,N,5,N,N,N }, //A顶点的边
{7,0,8,9,7,N,N }, //B顶点的边
{N,8,0,N,5,N,N }, //C顶点的边
{5,9,N,0,N,6,N }, //D顶点的边
{N,7,5,N,0,8,9 }, //E 顶点的边
{N,N,N,6,8,0,11 }, //F 顶点的边
{N,N,N,N,9,11,0 }, //G顶点的边
};
//已选的点集合
int[] vNew = new int[map.GetLength(0)];
//置为初始状态 ,此时未加入任何结点
for (int i = 0; i < vNew.Length; i++)
{
//N代表为加入结点
vNew[i] = N;
}
//加入初始结点
vNew[start] = Y;
int len = GetMST(vNew, map);
Console.WriteLine("最小生成树权值为:"+len);
Console.ReadKey();
}
/// <summary>
/// 普里姆算法
/// </summary>
/// <param name="vNew">已加入的结点,初始值需设定</param>
/// <param name="map">无向图的邻接矩阵</param>
/// <returns></returns>
private static int GetMST(int[] vNew,int[,]map)
{
//找出vNew点中与未选择的边组成的最小值
int length = 0;
while(vNew.Count(temp=>temp==Y)<map.GetLength(0))
{
int minLength = int.MaxValue;
int minNewNode = N;
int minStartNode = N;
for (int i = 0; i < vNew.Length; i++)
{
if (vNew[i] == Y)
{
for (int j = 0; j < map.GetLength(1); j++)
{
//未选择的结点已vNew中的结点组成的边
if (vNew[j] == N)
{
if (map[i, j] != N)
{
if (map[i, j] < minLength)
{
// Console.WriteLine("边{0}{1}", i, j);
minLength = map[i, j];
minNewNode = j;
minStartNode = i;
}
}
}
}
}
}
if (minNewNode==N)
{
//此处图的邻接矩阵数据不正确
throw new Exception("图的邻接矩阵数据不正确");
}
else
{
vNew[minNewNode] = Y;
Console.WriteLine("顶点{0}加入", ConvertToChar( minNewNode));
Console.WriteLine("边{0}--{1}加入", ConvertToChar(minStartNode), ConvertToChar(minNewNode));
length += minLength;
}
}
return length;
}
/// <summary>
/// 转换成字符,方便查看
/// </summary>
/// <param name="charValue"></param>
/// <returns></returns>
private static char ConvertToChar(int charValue)
{
int k = charValue + 65;
return (char)k;
}
}
}
Kruskal算法
加边法
浙公网安备 33010602011771号