最小生成树-普利姆算法eager实现

本文介绍了普利姆算法的一种eager实现方式,通过避免将不再候选的废边加入优先队列,使用索引式优先队列在常量时间内找到所需元素,从而优化了算法效率,使得最差情况下的时间复杂度为O(ElogV)。内容包括算法描述、实现分析、完整实现和时间复杂度的讨论。
摘要由CSDN通过智能技术生成

算法描述

在普利姆算法的lazy实现中,参考:普利姆算法的lazy实现
我们现在来考虑这样一个问题:

我们将所有的边都加入了优先队列,但事实上,我们真的需要所有的边吗?

我们再回到普利姆算法的lazy实现,看一下这个问题:
这里写图片描述
当顺着顶点0的邻接表考察顶点7时,边7-2和边7-1被加入了优先队列Q.

然而,当我们开始对顶点2进行考察时:
这里写图片描述

边2-3是最轻边,我们显然不需要对边7-2和边7-1进行再次考察.

但是,由于边7-2和边7-1在对顶点2进行考察之前已经加入了优先队列Q,似乎我们对之前发生的事无可奈何,也必须让优先队列维护着这些不再候选的废边,从而加重了优先队列的负担,影响了效率.

结果是否真的如此?
如果我们仔细思考,会注意到我们可以采取这样的一个技巧去防止将废边加入优先队列:

我们关注的只是当前能看到的最轻边,所以边7-2和边7-1对我们来说只有这样的意义:
边7-2:到顶点2的距离是x;
边7-1:到顶点2的距离是y;
边3-2:到顶点2的距离是z.
z > xz >y.

所以我们既然无法避免在先于顶点2之前就将边7-2和边7-1当做废边(贪心算法),所以我们可以

采取更新的方式来在优先队列Q中维护到某个顶点的最短距离.
换句话说,我们对某个顶点,只在Q中维护一条边,就是当前已知连着它的最轻边.

由此,我们避免了将所有的边都加入优先队列Q,从而使得最差情况下Q的操作与图的顶点数V 成线性渐进:O(V ).

但一般的优先队列只提供了入队(enqueue)和出队(dequeue)操作,要更新到某个顶点的最短距离,我们需要高效地在优先队列中访问这个顶点.
那么按照一般优先队列的方式,比如jdk中的优先队列,它会是这样:

    private int indexOf(Object o) {
        if (o != 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值