C#图的最小生成树算法

在VisualStudio2017中,新建控制台应用程序DemoMst。新建类 MinSpanningTree.cs。输入以下测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoMst
{
    /// <summary>
    /// 【图论】最小生成树
    /// </summary>
    public class MinSpanningTree
    {
        /// <summary>
        /// 无穷远的距离(权重),两点之间不能直接到达就认为是无穷的
        /// </summary>
        public const int Infinity = 99999;
        /// <summary>
        /// 顶点个数
        /// </summary>
        public const int VertexCount = 6;
        /// <summary>
        /// 顶点集合
        /// </summary>
        public string[] VertexCollection = new string[VertexCount];
        /// <summary>
        /// 点与点之间的距离(权重),两点不是直接相连,则默认距离是无穷(Infinity)的
        /// </summary>
        public int[,] Matrix = new int[VertexCount, VertexCount];

        /// <summary>
        /// 设置一个顶点
        /// </summary>
        /// <param name="index"></param>
        /// <param name="label"></param>
        public void SetVertex(int index, string label)
        {
            if (index < 0 || index >= VertexCount)
            {
                throw new Exception("顶点数组VertexCollection索引越界");
            }
            VertexCollection[index] = label;
        }
        /// <summary>
        /// 添加一条边【默认边为双向的】
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="distance"></param>
        public void AddEdge(int start, int end, int distance)
        {
            Matrix[start, end] = distance;
            //如果边Edge时双向的,则增加下面一行代码
            Matrix[end, start] = distance;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            //初始化顶点
            SetVertex(0, "A");
            SetVertex(1, "B");
            SetVertex(2, "C");
            SetVertex(3, "D");
            SetVertex(4, "E");
            SetVertex(5, "F");

            //初始化认为都无法直接到达,即:距离是无穷的
            for (int i = 0; i < VertexCount; i++)
            {
                for (int j = 0; j < VertexCount; j++)
                {
                    Matrix[i, j] = Infinity;
                }
            }

            //初始化可以直接到达的边
            //AB=3,AD=2,AF=7,
            //BC=4,BD=5,BE=6,
            //CE=4,CF=6,
            //DE=4,DF=4,
            //EF=3
            AddEdge(0, 1, 3);
            AddEdge(0, 3, 2);
            AddEdge(0, 5, 7);
            AddEdge(1, 2, 4);
            AddEdge(1, 3, 5);
            AddEdge(1, 4, 6);
            AddEdge(2, 4, 4);
            AddEdge(2, 5, 6);
            AddEdge(3, 4, 4);
            AddEdge(3, 5, 4);
            AddEdge(4, 5, 3);
        }

        /// <summary>
        /// 获取最小生成树
        /// </summary>
        public void GetMinSpanTree()
        {
            //初始定义一个集合,集合元素为空
            List<int> list = new List<int>();
            //第一个点A,其他点BCDEF
            int startIndex = 0;
            list.Add(startIndex);
            Console.WriteLine(string.Join(",", list));
            int nextIndex = GetNextMinVertex(list);
            //如果存在下一个节点,并且集合中不存在该元素
            if (nextIndex != -1 && !list.Contains(nextIndex))
            {
                list.Add(nextIndex);
                Console.WriteLine(string.Join(",", list));
            }
            while (list.Count < VertexCount)
            {
                nextIndex = GetNextMinVertex(list);
                if (nextIndex == -1)
                {
                    break;
                }
                if (nextIndex != -1 && !list.Contains(nextIndex))
                {
                    list.Add(nextIndex);
                    Console.WriteLine(string.Join(",", list));
                }
            }
        }

        /// <summary>
        /// 找出当前已选择起点集合可到达的顶点的当前最短距离的 索引,没有找到符合的则返回-1
        /// </summary>
        /// <param name="list">已找到的最短距离的顶点集合</param>
        /// <returns></returns>
        public int GetNextMinVertex(List<int> list)
        {
            int minIndex = -1;//到达顶点索引
            int minValue = Infinity;//两点间的距离
            int fromIndex = -1;//起始顶点索引
            for (int index = 0; index < list.Count; index++)
            {
                //以每一个已找到的最短距离的最小顶点作为起始顶点,穷举遍历出剩下的最短距离的下一个顶点
                int startIndex = list[index];
                for (int i = 0; i < VertexCount; i++)
                {
                    //贪婪法则,找出不存在集合中,最小的值的索引
                    if (!list.Contains(i) && Matrix[startIndex, i] < minValue)
                    {
                        minIndex = i;
                        minValue = Matrix[startIndex, i];
                        fromIndex = startIndex;
                    }
                }
            }
            Console.WriteLine("从【{0}】到【{1}】,当前距离:{0}{1}={2}", VertexCollection[fromIndex], VertexCollection[minIndex], minValue);
            return minIndex;
        }
    }
}
在默认的Program.cs中的Main函数中,测试代码如下:

 MinSpanningTree mst = new MinSpanningTree();
            mst.Init();
            mst.GetMinSpanTree();

            Console.ReadLine();

运行后结果截图:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值