最小生成树-Prim&Kruskal

最小生成树

加权图:是一种为每条边关联一个权值或是成本的图模型.

最小生成树MST(Minimum Spanning Tree):给定一幅加权无向图,找到它的一颗最小生成树(树中所有权值之和最小)

两种计算最小生成树的经典算法:Prim和Kruskal

  • Prim:已点为中心出发,最开始只有一个顶点,每次总是将下一条连接树中的顶点与不在树中的顶点且权重最小的边加入树中

  • Kruskal:以边的权重(从小到大)将边加入最小生成树中,加入的边不会与已生成的边构成环,直到树中含有V-1条边为止.

    如果存在权重值相同的情况,则任选一条边加入最小生成树中即可,可能会存在不同的生成树

    V指代顶点数量,E指代边的数量

Prim算法

可视化演示

代码实现两种方案:LazyPrim延迟实现和Prim即时实现:

延迟实现

延迟实现:将顶点的各条边均加入优先级队列,在边出队时再检查该边是否合法

  1. 选择一个顶点开始
  2. 将该顶点所有的边存入PriorityQueue中
  3. 循环当PriorityQueue非空时:
    1. 从队列取出一条边,如果这条边的另一顶点不再生成树中,则保存该条边到生成树中,否则继续循环(从队列中取边)
    2. 并将新加入生成树的顶点的其余边存入队列中
  4. 当队列为空时即得到最终最小生成树.

时间复杂度:ElogV

空间复杂度:E

及时实现

及时实现:相较于延迟实现,及时实现事先确定将要加入队列的边,即每个顶点仅入队一条边(权重最小的边)

  1. 选择一个顶点v开始
  2. 遍历所有顶点v的边,将所有边的另一顶点w及权重存入PriorityQueue
  3. 循环当PriorityQueue非空时:
    1. 从队列取出一条边,这条边和边的另一顶点w加入到生成树中
    2. 遍历顶点w所有的边,找到顶点w所有边另一顶点不在树中的顶点u顶点u及其权重存入PriorityQueue
    3. 如果队列中已存在顶点u则比较权重,如果新的边权重更新则更新队列中的记录,否则保留队列中的边
  4. 当队列为空时即得到最终最小生成树.

时间复杂度:ElogV

空间复杂度:V

Kruskal算法

可视化演示

代码实现:优先级队列PriorityQueue和union-find

使用优先级队列保存所有的边,使用uf联通各个顶点

  1. 将所有的边存入优先级队列
  2. 循环从队列中取数据,直到队列为空或者生成树已有V-1条边
    1. 从队列中取出边,根据uf判断该边的顶点是否已经联通,如已联通则该边非法,继续循环continue
    2. uf联通该边的两点,并将该边加入到生成树中
  3. 循环结束及得到最小生成树.

时间复杂度:ElogE

空间复杂度:E

posted @   Abserver  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示