heap sort
This commit is contained in:
parent
ebe6a3ab37
commit
d4cbad40c3
4 changed files with 67 additions and 2 deletions
55
sorting/heap.go
Normal file
55
sorting/heap.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package sorting
|
||||
|
||||
func swap[T any](i, j int, items []T) {
|
||||
items[i], items[j] = items[j], items[i]
|
||||
}
|
||||
|
||||
func swim[T any](child int, depth int, items []T, less func(T, T) bool) {
|
||||
for {
|
||||
parent := (child - 1) / 2
|
||||
|
||||
if child <= 0 || less(items[child], items[parent]) {
|
||||
break
|
||||
}
|
||||
|
||||
swap(parent, child, items)
|
||||
|
||||
child = parent
|
||||
}
|
||||
}
|
||||
|
||||
func sink[T any](parent int, depth int, items []T, less func(T, T) bool) {
|
||||
for {
|
||||
child := parent*2 + 1
|
||||
|
||||
if child >= depth {
|
||||
break
|
||||
}
|
||||
|
||||
if child+1 < depth && less(items[child], items[child+1]) {
|
||||
child++
|
||||
}
|
||||
|
||||
if !less(items[parent], items[child]) {
|
||||
break
|
||||
}
|
||||
|
||||
swap(parent, child, items)
|
||||
|
||||
parent = child
|
||||
}
|
||||
}
|
||||
|
||||
func Heap[T any](items []T, less func(T, T) bool) {
|
||||
len := len(items)
|
||||
|
||||
for k := len / 2; k >= 0; k-- {
|
||||
sink(k, len, items, less)
|
||||
}
|
||||
|
||||
for len > 0 {
|
||||
len--
|
||||
swap(0, len, items)
|
||||
sink(0, len, items, less)
|
||||
}
|
||||
}
|
|
@ -15,8 +15,6 @@ func TestNewIPQ(t *testing.T) {
|
|||
assert.Equal(t, 0, q.Size())
|
||||
assert.Equal(t, true, q.IsEmpty())
|
||||
assert.Equal(t, -1, q.TopIndex())
|
||||
// TODO: maybe should return nil?
|
||||
// assert.Equal(t, 0, q.Top())
|
||||
}
|
||||
|
||||
func TestIPQInsert(t *testing.T) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
package sorting
|
||||
|
||||
// TODO: compare function should receive pointers to slice elements
|
||||
// to prevent unnecessary coping
|
||||
type SliceSorter[T any] func([]T, func(T, T) bool)
|
||||
|
|
|
@ -73,3 +73,13 @@ func BenchmarkQuick(b *testing.B) {
|
|||
BenchmarkSort(10000, Quick[int])
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeap(t *testing.T) {
|
||||
CheckSliceSorter(Heap[int])
|
||||
}
|
||||
|
||||
func BenchmarkHeap(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
BenchmarkSort(10000, Heap[int])
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue