// Removes and returns the minimum element of h. func PopMin(h heap.Interface) interface{} { n := h.Len() - 1 h.Swap(0, n) x := h.Pop() siftDownMin(h, 0, n) return x }
func siftDownMin(h heap.Interface, i, n int) { for (i*2+2)*2+2 < n { // has four grandchildren m := minGrandchild(h, i, n) if h.Less(i, m) { return } h.Swap(i, m) if h.Less(parent(m), m) { h.Swap(m, parent(m)) } i = m } if hasChild(i, n) { m := minTwoGen(h, i, n) if m > i*2+2 { // must be a grandchild if h.Less(m, i) { h.Swap(i, m) if h.Less(parent(m), m) { h.Swap(m, parent(m)) } siftDownMin(h, m, n) } } else if h.Less(m, i) { h.Swap(i, m) } } }
// Iterative version after Bojesen, "Heap implementations and variations", // http://www.diku.dk/forskning/performance-engineering/Jesper/heaplab/heapsurvey_html/node11.html func siftDownMax(h heap.Interface, i, n int) { for (i*2+2)*2+2 < n { // has four grandchildren m := maxGrandchild(h, i, n) if h.Less(m, i) { return } h.Swap(i, m) if h.Less(m, parent(m)) { h.Swap(m, parent(m)) } i = m } // XXX Following is from the original paper; couldn't get Bojesen's version // to work. if hasChild(i, n) { m := maxTwoGen(h, i, n) if m > i*2+2 { // must be a grandchild if h.Less(i, m) { h.Swap(i, m) if h.Less(m, parent(m)) { h.Swap(m, parent(m)) } siftDownMax(h, m, n) } } else if h.Less(i, m) { h.Swap(i, m) } } }
func siftUpMin(h heap.Interface, i int) { for gp := parent(parent(i)); gp >= 0; i, gp = gp, parent(parent(gp)) { if h.Less(gp, i) { break } h.Swap(i, gp) } }
// Removes and returns the maximum element of h. func PopMax(h heap.Interface) interface{} { n := h.Len() if n <= 2 { return h.Pop() } i := 1 if h.Less(1, 2) { i = 2 } h.Swap(i, n-1) x := h.Pop() siftDownMax(h, i, n-1) return x }
func siftUp(h heap.Interface, i int) { if minLevel(i) { if i > 0 && h.Less(parent(i), i) { h.Swap(i, parent(i)) siftUpMax(h, parent(i)) } else { siftUpMin(h, i) } } else { if i > 0 && h.Less(i, parent(i)) { h.Swap(i, parent(i)) siftUpMin(h, parent(i)) } else { siftUpMax(h, i) } } }