mirror of
https://github.com/golang/go
synced 2024-11-12 09:50:21 -07:00
heap algorithm
R=rsc DELTA=196 (194 added, 0 deleted, 2 changed) OCL=34234 CL=34263
This commit is contained in:
parent
e10ca39d04
commit
115c62de8d
@ -3,10 +3,11 @@ base64.install: bytes.install io.install os.install strconv.install
|
||||
big.install:
|
||||
bignum.install: fmt.install
|
||||
bufio.install: io.install os.install strconv.install utf8.install
|
||||
bytes.install: os.install utf8.install
|
||||
bytes.install: os.install unicode.install utf8.install
|
||||
compress/flate.install: bufio.install io.install os.install strconv.install
|
||||
compress/gzip.install: bufio.install compress/flate.install hash.install hash/crc32.install io.install os.install
|
||||
compress/zlib.install: bufio.install compress/flate.install hash.install hash/adler32.install io.install os.install
|
||||
container/heap.install: sort.install
|
||||
container/list.install:
|
||||
container/ring.install:
|
||||
container/vector.install:
|
||||
@ -53,7 +54,7 @@ rpc.install: bufio.install fmt.install gob.install http.install io.install log.i
|
||||
runtime.install:
|
||||
sort.install:
|
||||
strconv.install: bytes.install math.install os.install unicode.install utf8.install
|
||||
strings.install: utf8.install
|
||||
strings.install: unicode.install utf8.install
|
||||
sync.install:
|
||||
syscall.install: sync.install
|
||||
tabwriter.install: bytes.install container/vector.install io.install os.install utf8.install
|
||||
|
@ -21,6 +21,7 @@ DIRS=\
|
||||
compress/flate\
|
||||
compress/gzip\
|
||||
compress/zlib\
|
||||
container/heap\
|
||||
container/list\
|
||||
container/ring\
|
||||
container/vector\
|
||||
|
11
src/pkg/container/heap/Makefile
Normal file
11
src/pkg/container/heap/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# 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.
|
||||
|
||||
include $(GOROOT)/src/Make.$(GOARCH)
|
||||
|
||||
TARG=container/heap
|
||||
GOFILES=\
|
||||
heap.go\
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
82
src/pkg/container/heap/heap.go
Normal file
82
src/pkg/container/heap/heap.go
Normal file
@ -0,0 +1,82 @@
|
||||
// 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
|
||||
// HeapInterface.
|
||||
//
|
||||
package heap
|
||||
|
||||
import "sort"
|
||||
|
||||
// Any type that implements HeapInterface may be used as a
|
||||
// heap with the following invariants (established after Init
|
||||
// has been called):
|
||||
//
|
||||
// h.Less(i, j) for 0 <= i < h.Len() and j = 2*i+1 or 2*i+2 and j < h.Len()
|
||||
//
|
||||
type HeapInterface interface {
|
||||
sort.SortInterface;
|
||||
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*log(n)) where n = h.Len().
|
||||
//
|
||||
func Init(h HeapInterface) {
|
||||
sort.Sort(h);
|
||||
}
|
||||
|
||||
|
||||
// Push pushes the element x onto the heap. The complexity is
|
||||
// O(log(n)) where n = h.Len().
|
||||
//
|
||||
func Push(h HeapInterface, 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().
|
||||
//
|
||||
func Pop(h HeapInterface) interface{} {
|
||||
n := h.Len()-1;
|
||||
h.Swap(0, n);
|
||||
down(h, 0, n);
|
||||
return h.Pop();
|
||||
}
|
||||
|
||||
|
||||
func up(h HeapInterface, j int) {
|
||||
for {
|
||||
i := (j-1)/2;
|
||||
if i == j || h.Less(i, j) {
|
||||
break;
|
||||
}
|
||||
h.Swap(i, j);
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func down(h HeapInterface, i, n int) {
|
||||
for {
|
||||
j := 2*i + 1;
|
||||
if j >= n {
|
||||
break;
|
||||
}
|
||||
if j1 := j+1; j1 < n && !h.Less(j, j1) {
|
||||
j = j1; // = 2*i + 2
|
||||
}
|
||||
if h.Less(i, j) {
|
||||
break;
|
||||
}
|
||||
h.Swap(i, j);
|
||||
i = j;
|
||||
}
|
||||
}
|
99
src/pkg/container/heap/heap_test.go
Normal file
99
src/pkg/container/heap/heap_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"testing";
|
||||
"container/vector";
|
||||
)
|
||||
|
||||
|
||||
type myHeap struct {
|
||||
vector.IntVector;
|
||||
}
|
||||
|
||||
|
||||
func newHeap() *myHeap {
|
||||
var h myHeap;
|
||||
h.IntVector.Init(0);
|
||||
return &h;
|
||||
}
|
||||
|
||||
|
||||
func (h *myHeap) verify(t *testing.T, i int) {
|
||||
n := h.Len();
|
||||
j1 := 2*i + 1;
|
||||
j2 := 2*i + 2;
|
||||
if j1 < n {
|
||||
if h.Less(j1, i) {
|
||||
t.Errorf("heap invariant invalidated [%d] = %d > [%d] = %d", i, h.At(i), j1, h.At(j1));
|
||||
return;
|
||||
}
|
||||
h.verify(t, j1);
|
||||
}
|
||||
if j2 < n {
|
||||
if h.Less(j2, i) {
|
||||
t.Errorf("heap invariant invalidated [%d] = %d > [%d] = %d", i, h.At(i), j1, h.At(j2));
|
||||
return;
|
||||
}
|
||||
h.verify(t, j2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (h *myHeap) Push(x interface{}) {
|
||||
h.IntVector.Push(x.(int));
|
||||
}
|
||||
|
||||
|
||||
func (h *myHeap) Pop() interface{} {
|
||||
return h.IntVector.Pop();
|
||||
}
|
||||
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
h := newHeap();
|
||||
for i := 20; i > 0; i-- {
|
||||
h.Push(i);
|
||||
}
|
||||
Init(h);
|
||||
h.verify(t, 0);
|
||||
|
||||
for i := 1; h.Len() > 0; i++ {
|
||||
x := Pop(h).(int);
|
||||
h.verify(t, 0);
|
||||
if x != i {
|
||||
t.Errorf("%d.th pop got %d; want %d", i, x, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func Test(t *testing.T) {
|
||||
h := newHeap();
|
||||
h.verify(t, 0);
|
||||
|
||||
for i := 20; i > 10; i-- {
|
||||
h.Push(i);
|
||||
}
|
||||
Init(h);
|
||||
h.verify(t, 0);
|
||||
|
||||
for i := 10; i > 0; i-- {
|
||||
Push(h, i);
|
||||
h.verify(t, 0);
|
||||
}
|
||||
|
||||
for i := 1; h.Len() > 0; i++ {
|
||||
x := Pop(h).(int);
|
||||
if i < 20 {
|
||||
Push(h, 20+i);
|
||||
}
|
||||
h.verify(t, 0);
|
||||
if x != i {
|
||||
t.Errorf("%d.th pop got %d; want %d", i, x, i);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user