最小生成树

最小生成树:无向图G的最小生成树是连接G的所有顶点的边构成的树,并且总价值最低,最小生成树存在当且仅当图是连通的。最小生成树不是唯一的,它是树,因为无圈;是生成树,因为包含每一个顶点。有两种算法

1.Prim算法

是贪婪算法,分步进行,每一步,都把一个顶点当作根加入树中。在每个阶段,有一个已知顶点的集合,其余顶点未知,选择未知顶点中到已知顶点集中距离最短的,声明为已知并加入到树中,代码如下:

/* 最小生成树的Prim算法 */
void Prim()
{
    Vertex V, W;

    for (;;)
    {
        V = smallest unknown distance vertex;
        if (V == NotAVertex)
            break;
        for each W adjacnet to V
            if (!T[W].Known)
                /* 这个判断条件和dijkstra算法不同,不用考虑历史路径长度 */
                if (Cvw < T[W].Dist)
                {
                    Decrease(T[W].Dist to Cvw);
                    T[W].Path = V:
                }
    }
}

和Dijkstra算法思想是一样的,只是更新时候判断条件不同

2.Kruskal算法

是贪婪算法,和Prim算法的区别是,每个阶段贪婪的是最小的边,而不是距离最短的未知顶点,只要贪婪的边不产生圈,就加入进来。Kruskal算法基于的基础数据结构是不相交集,代码如下:

/* 最小生成树的Kruskal算法 */
void Kruskal(Graph G)
{
    int EdgeAccepted;
    DisjSet S;
    PriorityQueue H;
    Vertex U, V;
    SetType Uset, Vset;
    Edge E;

    /* 将顶点存入到不相交集中 */
    Initialize(S);
    /* 将图中每条边读入优先队列中 */
    ReadGraphIntoHeapArray(G, H);
    BuildHeap(H);

    EdgeAccepted = 0;
    while (EdgeAccepted < NumVertex - 1)
    {
        /* 从优先队列中找最小的边,U和V是这个边的两个顶点 */
        E = DeleteMin(H);
        Vset = Find(U, S);
        Uset = Find(V, S);
        /* 若两个顶点不在一个集合中,那么说明有一个顶点不在树种,合并,否则已经在了,继续找
         * 下一个最小的边*/
        if (Uset != Vset)
        {
            EdgeAccepted++;
            SetUnion(S, Uset, Vset);
        }
    }
}

最坏时间是O(|E|log|E|)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值