最小生成树算法(类Prim算法的笨办法)

这个算法是我自己想的最笨最原始的算法,原理跟Prim类似,但不同的是这里不用处理最小优先级队列,当然算法的时间复杂度要高些(该算法针对的是无向连通图,对于有向连通图,算法原理一样,但算法代码需要做一些处理),下面看代码:

1、类和树的定义可参考前面的博文。

2、算法类:

public class PrimAlg
    {
        public Tree MST_SimpleAlg(Graphic g,Node root)
        {
            Tree theMST = new Tree();
            //最小生成树节点
            Dictionary<string, Node> theMstNodes = new Dictionary<string, Node>();
            //剩下未纳入最小生成树的节点
            Dictionary<string, Node> theRemainNodes = new Dictionary<string, Node>();
            //图的边
            List<Edge> theEdges = new List<Edge>();
            //开始的时候最小生成树节点包含root一个节点.
            theMstNodes.Add(root.Symbol, root);
            //将图的边复制到临时边集中,目的是没选一个边,就可以删除该边,以减低时间复杂度。
            theEdges.AddRange(g.Edges);
            //开始的时候剩余点集是图中除根节点之外的所有点.
            foreach (var theNode in g.Nodes)
            {
                if (theNode.Symbol != root.Symbol)
                {
                    theRemainNodes.Add(theNode.Symbol, theNode);
                }
            }
            //将根节点放入结果最小生成树中.
            theMST.Nodes.Add(root);
            //只要有剩余点就循环处理
            while (theRemainNodes.Count() > 0)
            {
                //记录最小的边,该边一个节点在已生成的最小生成树节点中,
                //一个节点在未纳入最小生成树的节点中
                Edge theMinEdge = null;
                //最小边在最小生成树中的节点
                Node theMNode = null;
                //最小边在剩余节点中端点.
                Node theRNode = null;
                foreach (var theEdge in theEdges)
                {
                    if (theMstNodes.ContainsKey(theEdge.Node1.Symbol) &&
                        theRemainNodes.ContainsKey(theEdge.Node2.Symbol))
                    {
                        if (theMinEdge == null)
                        {
                            theMinEdge = theEdge;
                            theMNode = theEdge.Node1;
                            theRNode = theEdge.Node2;
                            continue;
                        }
                        if (theMinEdge.Weight > theEdge.Weight)
                        {
                            theMinEdge = theEdge;
                            theMNode = theEdge.Node1;
                            theRNode = theEdge.Node2;
                            continue;
                        }
                    }
                    if (theMstNodes.ContainsKey(theEdge.Node2.Symbol) &&
                         theRemainNodes.ContainsKey(theEdge.Node1.Symbol))
                    {
                        if (theMinEdge == null)
                        {
                            theMinEdge = theEdge;
                            theMNode = theEdge.Node2;
                            theRNode = theEdge.Node1;
                            continue;
                        }
                        if (theMinEdge.Weight > theEdge.Weight)
                        {
                            theMinEdge = theEdge;
                            theMNode = theEdge.Node2;
                            theRNode = theEdge.Node1;
                            continue;
                        }
                    }     
                }
                if (theMinEdge != null)
                {
                    theMST.Nodes.Add(theRNode);
                    theMST.Edges.Add(theMinEdge);
                    theMstNodes.Add(theRNode.Symbol,theRNode);
                    theRemainNodes.Remove(theRNode.Symbol);
                    theEdges.Remove(theMinEdge);
                }
            }
            return theMST;
        }
    }

这个算法的复杂度虽然比较高o(E2),但实现非常简单,不需要像Prim算法那样用到二叉堆之类的,容易理解和实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值