最小生成树-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算法
加边法