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

加边法

posted @ 2024-03-28 00:49  yinghualeihenmei  阅读(3)  评论(0编辑  收藏  举报