| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // This package provides heap operations for any type that implements |
| // heap.Interface. |
| // |
| package heap |
| |
| import "sort" |
| |
| // Any type that implements heap.Interface may be used as a |
| // min-heap with the following invariants (established after |
| // Init has been called): |
| // |
| // !h.Less(j, i) for 0 <= i < h.Len() and j = 2*i+1 or 2*i+2 and j < h.Len() |
| // |
| type Interface interface { |
| sort.Interface |
| Push(x interface{}) |
| Pop() interface{} |
| } |
| |
| |
| // A heaper must be initialized before any of the heap operations |
| // can be used. Init is idempotent with respect to the heap invariants |
| // and may be called whenever the heap invariants may have been invalidated. |
| // Its complexity is O(n) where n = h.Len(). |
| // |
| func Init(h Interface) { |
| // heapify |
| n := h.Len() |
| for i := n/2 - 1; i >= 0; i-- { |
| down(h, i, n) |
| } |
| } |
| |
| |
| // Push pushes the element x onto the heap. The complexity is |
| // O(log(n)) where n = h.Len(). |
| // |
| func Push(h Interface, x interface{}) { |
| h.Push(x) |
| up(h, h.Len()-1) |
| } |
| |
| |
| // Pop removes the minimum element (according to Less) from the heap |
| // and returns it. The complexity is O(log(n)) where n = h.Len(). |
| // Same as Remove(h, 0). |
| // |
| func Pop(h Interface) interface{} { |
| n := h.Len() - 1 |
| h.Swap(0, n) |
| down(h, 0, n) |
| return h.Pop() |
| } |
| |
| |
| // Remove removes the element at index i from the heap. |
| // The complexity is O(log(n)) where n = h.Len(). |
| // |
| func Remove(h Interface, i int) interface{} { |
| n := h.Len() - 1 |
| if n != i { |
| h.Swap(i, n) |
| down(h, i, n) |
| up(h, i) |
| } |
| return h.Pop() |
| } |
| |
| |
| func up(h Interface, j int) { |
| for { |
| i := (j - 1) / 2 // parent |
| if i == j || h.Less(i, j) { |
| break |
| } |
| h.Swap(i, j) |
| j = i |
| } |
| } |
| |
| |
| func down(h Interface, i, n int) { |
| for { |
| j1 := 2*i + 1 |
| if j1 >= n { |
| break |
| } |
| j := j1 // left child |
| if j2 := j1 + 1; j2 < n && !h.Less(j1, j2) { |
| j = j2 // = 2*i + 2 // right child |
| } |
| if h.Less(i, j) { |
| break |
| } |
| h.Swap(i, j) |
| i = j |
| } |
| } |