Prim的算法:如何获取要执行DECREASE_KEY操作的密钥索引?

时间:2017-12-28 09:32:46

标签: algorithm graph time-complexity prims-algorithm

所以我正在遵循这个算法用于Prim的MST

输入:邻接列表形式的图G(V,E)

  1. 使用构建堆时间复杂度为顶点创建最小堆:O(V)
  2. 重复以下步骤,直到堆中没有更多元素。
  3. 在堆上调用extract-min以获得具有最小成本O(log V)的顶点
  4. 对于提取的顶点,找到邻接列表中的相邻顶点。
  5. 对堆中的相邻顶点执行减少键操作。 O(logn V)
  6. 我班上给出的算法的时间复杂度分析如下:

    O(V) => to build heap
    O(VlogV) => V times EXTRACT_MIN operation
    2E => traverse all edges in adjacency list
    ElogV => E times DECREASE_KEY operation (Worst Case)
    
    EXTRACT_MIN => O(logV)
    DECREASE_KEY => O(logV)
    
    Total Time Complexity = V + V*logV + 2E + E*log V
                          = O((V+E) logV)
    

    我的问题是在执行decease键操作之前我不需要在min heap中找到相应的元素吗?并且搜索堆中的元素将花费O(V)时间。

    Example:

    对于上图,我会做这样的事情(使用数组实现最小堆)

                          A    B    C    D   E   F
                        ----------------------------------
     chosen as min        0   INF  INF  INF INF INF  ------> cost associated with vertices
                        ------------------------------
     A                        7    2    6   INF INF
                         ------------------------------
     C                        6         6    8   5
                         ------------------------------
     F                        6         3    7
                         ------------------------------
     D                        6              7
                         ------------------------------
     B                                       4
                         ------------------------------
     E
    

    我的数组(最小堆)最初看起来像这样: 每个元素由两部分组成:顶点名称和成本。 最小堆基于成本。

     A,0 | B,INF | C,INF | D,INF | E,INF | F,INF
    

    现在在获得第一个最小元素(A)后,我在邻接列表中查找其相邻顶点 找到B,C和D.现在我需要对最小堆中的这些顶点执行减少键操作。

    只有当我知道要执行减少键操作的顶点索引时,DECREASE_KEY操作才有效。 要获得索引,我不需要首先在数组中搜索它需要额外的O(V)吗?

1 个答案:

答案 0 :(得分:1)

好吧,你可以以你想要的方式解决这个问题。它需要将指针从每个顶点保持回到堆中的索引。每当交换堆中的元素时,都会调整两个相关顶点上的指针。然后,当您需要调整顶点的键时,您可以将指针移回堆中的索引。

但是,我通常不这样做......

我通常将(成本,顶点)记录放在堆中,每当顶点的成本下降时,我就会添加一个新的记录。当我从堆中弹出一个顶点时,如果它已经完成,我就忽略它。你必须跟踪最终完成的顶点,这很容易。

这需要O(| E |)空格而不是O(| V |),但这通常不是什么大问题,时间复杂度保持不变。