https://github.com/twmb/go-sliceheap
A Go package to provide heaps on arbitrary slices.
https://github.com/twmb/go-sliceheap
Last synced: 8 months ago
JSON representation
A Go package to provide heaps on arbitrary slices.
- Host: GitHub
- URL: https://github.com/twmb/go-sliceheap
- Owner: twmb
- License: mit
- Created: 2019-08-13T07:32:31.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2023-04-05T04:31:19.000Z (about 3 years ago)
- Last Synced: 2025-02-01T03:43:16.434Z (over 1 year ago)
- Language: Go
- Size: 9.77 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
go-sliceheap
============
Package sliceheap returns a quick heap given a pointer to a slice and a less
function (akin to sort.Slice for sorting slices).
This package is for that rare time when you need a heap and do not want to make
an arbitrary type to provide `Push` and `Pop`.
Documentation
-------------
[](https://godoc.org/github.com/twmb/go-sliceheap)
Example
-------
```go
// we can create heap in one function and return it.
inner := func() sliceheap.Heap[int] {
a := []int{3, 2, 4, 5, 1, 0, 6}
h := sliceheap.On(&a, func(i, j int) bool { return a[i] > a[j] })
heap.Init(h)
return h
}
h := inner()
// We can see the heap sort itself by checking the backing slice.
fmt.Println(h.View()) // prints [6 5 4 2 1 0 3]
heap.Push(h, 8) // push a few more elements...
// If we want to observe pushes and pops from the slice, we must save a
// pointer to the slice. This is only necessary if working on a slice
// that you did not pass directly to sliceheap.On, i.e., if you have lost
// the original pointer you used.
ptr := h.Pointer()
fmt.Println(*ptr) // prints [8 6 4 5 1 0 3 2]
heap.Push(h, 7)
fmt.Println(*ptr) // prints [8 7 4 6 1 0 3 2 5]
heap.Push(h, 7)
heap.Push(h, 9)
// Pop everything off, printing as we pop largest to smallest.
for h.Len() > 0 {
largest := heap.Pop(h).(int)
fmt.Println(largest) // prints 9, 8, 7...
}
```
Benchmarks
----------
The following benchmark shows creating a slice of N nodes, and then constantly
pushing a new largest element onto it and popping the smallest. The new largest
element constantly sifts to the bottom, then smallest sifts out to be popped.
On go1.20.2
```
BenchmarkPushPop/1_nodes-8 18511695 65.84 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/2_nodes-8 17404094 68.47 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/4_nodes-8 15398985 77.69 ns/op 48 B/op 3 allocs/op
BenchmarkPushPop/8_nodes-8 13573598 87.86 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/16_nodes-8 11884834 99.30 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/32_nodes-8 10706637 111.5 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/64_nodes-8 9599702 125.0 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/128_nodes-8 8897252 135.6 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/256_nodes-8 8381521 146.2 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/512_nodes-8 8005512 153.4 ns/op 47 B/op 3 allocs/op
BenchmarkPushPop/1024_nodes-8 7690998 162.2 ns/op 47 B/op 3 allocs/op
```