mirror of https://github.com/golang/go.git
container/heap: add Fix and document the min is element 0.
Fixes #5372. Fixes #5577. R=gri, rsc, bradfitz, r CC=golang-dev https://golang.org/cl/12265043
This commit is contained in:
parent
37feacf623
commit
dd6f49ddca
|
|
@ -31,13 +31,17 @@ func (h *IntHeap) Pop() interface{} {
|
|||
return x
|
||||
}
|
||||
|
||||
// This example inserts several ints into an IntHeap and removes them in order of priority.
|
||||
// This example inserts several ints into an IntHeap, checks the minimum,
|
||||
// and removes them in order of priority.
|
||||
func Example_intHeap() {
|
||||
h := &IntHeap{2, 1, 5}
|
||||
heap.Init(h)
|
||||
heap.Push(h, 3)
|
||||
fmt.Printf("minimum: %d\n", (*h)[0])
|
||||
for h.Len() > 0 {
|
||||
fmt.Printf("%d ", heap.Pop(h))
|
||||
}
|
||||
// Output: 1 2 3 5
|
||||
// Output:
|
||||
// minimum: 1
|
||||
// 1 2 3 5
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
// heap.Interface. A heap is a tree with the property that each node is the
|
||||
// minimum-valued node in its subtree.
|
||||
//
|
||||
// The minimum element in the tree is the root, at index 0.
|
||||
//
|
||||
// A heap is a common way to implement a priority queue. To build a priority
|
||||
// queue, implement the Heap interface with the (negative) priority as the
|
||||
// ordering for the Less method, so Push adds items while Pop removes the
|
||||
|
|
@ -54,7 +56,7 @@ func Push(h Interface, x interface{}) {
|
|||
|
||||
// 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).
|
||||
// It is equivalent to Remove(h, 0).
|
||||
//
|
||||
func Pop(h Interface) interface{} {
|
||||
n := h.Len() - 1
|
||||
|
|
@ -76,6 +78,15 @@ func Remove(h Interface, i int) interface{} {
|
|||
return h.Pop()
|
||||
}
|
||||
|
||||
// Fix reestablishes the heap ordering after the element at index i has changed its value.
|
||||
// Changing the value of the element at index i and then calling Fix is equivalent to,
|
||||
// but less expensive than, calling Remove(h, i) followed by a Push of the new value.
|
||||
// The complexity is O(log(n)) where n = h.Len().
|
||||
func Fix(h Interface, i int) {
|
||||
down(h, i, h.Len())
|
||||
up(h, i)
|
||||
}
|
||||
|
||||
func up(h Interface, j int) {
|
||||
for {
|
||||
i := (j - 1) / 2 // parent
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
package heap
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -182,3 +183,31 @@ func BenchmarkDup(b *testing.B) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFix(t *testing.T) {
|
||||
h := new(myHeap)
|
||||
h.verify(t, 0)
|
||||
|
||||
for i := 200; i > 0; i -= 10 {
|
||||
Push(h, i)
|
||||
}
|
||||
h.verify(t, 0)
|
||||
|
||||
if (*h)[0] != 10 {
|
||||
t.Fatalf("Expected head to be 10, was %d", (*h)[0])
|
||||
}
|
||||
(*h)[0] = 210
|
||||
Fix(h, 0)
|
||||
h.verify(t, 0)
|
||||
|
||||
for i := 100; i > 0; i-- {
|
||||
elem := rand.Intn(h.Len())
|
||||
if i&1 == 0 {
|
||||
(*h)[elem] *= 2
|
||||
} else {
|
||||
(*h)[elem] /= 2
|
||||
}
|
||||
Fix(h, elem)
|
||||
h.verify(t, 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue