问题
So I am following this algorithm for Prim's MST
input: graph G(V,E) in the form of adjacency list
- Create a min heap for vertices using build heap time complexity: O(V)
- Repeat following steps until no more elements in heap.
- Call extract-min on heap to get vertex with minimum cost O(log V)
- For vertex extracted find the adjacent vertices in adjacency list.
- Perform decrease key operation on adjacent vertices in the heap. O(logn V)
The time complexity analysis for the algorithm given in my class goes something like this:
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)
My question is before performing decease key operation won't I need to find the corresponding element in the min heap? And searching the element in the heap would take O(V) time.
For the above graph I would do something like this (min heap implemented using array)
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
My array (min heap) would initially look like this : Each element consists of two things: the vertex name, the cost. The min heap is based on cost.
A,0 | B,INF | C,INF | D,INF | E,INF | F,INF
Now after getting first minimum element (A) I look for its adjacent vertices in adjacency list and find B, C and D. Now I need to perform decrease key operation for these vertices in the min heap.
The DECREASE_KEY operation would work only if I know the index of the vertex on which decrease key operation is to be performed. To get the index won't I need to first search for it in the array taking O(V) additional time?
回答1:
Well, you can solve this problem the way you want. It requires keeping pointers back from each vertex to its index in the heap. Whenever elements in the heap are swapped, the pointers on the two associated vertexes are adjusted. Then when you need to adjust the key for a vertex you can follow the pointer back to its index in the heap.
However, I usually don't do it that way...
I usually put (cost,vertex) records in the heap, and whenever the cost for a vertex goes down, I just put in a new one. When I pop a vertex out of the heap, then, I just ignore it if it's already done. You have to keep track of which vertexes are done anyway, so that is easy.
This takes O(|E|) space instead of O(|V|), but that's usually not a big deal, and the time complexity stays the same.
来源:https://stackoverflow.com/questions/48004917/prims-algorithm-how-to-get-index-of-key-on-which-decrease-key-operation-is-to