|
| 1 | +package minheapmap |
| 2 | + |
| 3 | +import "container/heap" |
| 4 | + |
| 5 | +// The Interface type describes the requirements |
| 6 | +// for a type using the routines in this package. |
| 7 | +// Any type that implements it may be used as a |
| 8 | +// min-heap with the keys stored in a map |
| 9 | + |
| 10 | +type Interface interface { |
| 11 | +heap.Interface |
| 12 | +//Remove an element from the corresponding Map for the heap entries |
| 13 | +Remove(x interface{}) |
| 14 | +//Update a particular value of an entry in the heap and re-evaluate the heap invariance |
| 15 | +Update(k, v interface{}) |
| 16 | +//Get the elem present at a particular index in the heap array |
| 17 | +GetElem(x interface{}) interface{} |
| 18 | +//Get the correspinding value to a key in the Map for the heap entries |
| 19 | +GetKey(x interface{}) int |
| 20 | +} |
| 21 | + |
| 22 | +//Decrease the value associated with the key in the <key,value> tuple |
| 23 | +func Decrease(h Interface, k interface{}) { |
| 24 | +p := h.GetKey(k) |
| 25 | +if !down(h, p, h.Len()) { |
| 26 | +up(h, p) |
| 27 | +} |
| 28 | +} |
| 29 | + |
| 30 | +// Push pushes the element x onto the heap. |
| 31 | +// The complexity is O(log n) where n = h.Len(). |
| 32 | +// Push() is for the interface to call and should be used to add keys to the heap |
| 33 | +func Push(h Interface, x interface{}) { |
| 34 | +h.Push(x) |
| 35 | +up(h, h.Len()-1) |
| 36 | +} |
| 37 | + |
| 38 | +// Pop removes and returns the minimum element (according to Less) from the heap. |
| 39 | +func Pop(h Interface) interface{} { |
| 40 | +n := h.Len() - 1 |
| 41 | +h.Remove(h.GetElem(0)) |
| 42 | +h.Update(h.GetElem(n), 0) |
| 43 | +h.Swap(0, n) |
| 44 | +down(h, 0, n) |
| 45 | +return h.Pop() |
| 46 | +} |
| 47 | + |
| 48 | +func up(h Interface, j int) { |
| 49 | +for { |
| 50 | +i := (j - 1) / 2 // parent |
| 51 | +if i == j || !h.Less(j, i) { |
| 52 | +break |
| 53 | +} |
| 54 | +h.Update(h.GetElem(i), j) |
| 55 | +h.Update(h.GetElem(j), i) |
| 56 | +h.Swap(i, j) |
| 57 | +j = i |
| 58 | +} |
| 59 | +return |
| 60 | +} |
| 61 | + |
| 62 | +func down(h Interface, i0, n int) bool { |
| 63 | +i := i0 |
| 64 | +for { |
| 65 | +j1 := 2*i + 1 |
| 66 | +if j1 >= n || j1 < 0 { // j1 < 0 after int overflow |
| 67 | +break |
| 68 | +} |
| 69 | +j := j1 // left child |
| 70 | +if j2 := j1 + 1; j2 < n && h.Less(j2, j1) { |
| 71 | +j = j2 // = 2*i + 2 // right child |
| 72 | +} |
| 73 | +if !h.Less(j, i) { |
| 74 | +break |
| 75 | +} |
| 76 | +h.Update(h.GetElem(i), j) |
| 77 | +h.Update(h.GetElem(j), i) |
| 78 | +h.Swap(i, j) |
| 79 | +i = j |
| 80 | +} |
| 81 | +return i > i0 |
| 82 | +} |
0 commit comments