mirror of git://gcc.gnu.org/git/gcc.git
97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
// 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.
|
|
|
|
// Package heap 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 heap 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
|
|
}
|
|
}
|