114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
package ds
|
|
|
|
import (
|
|
"math/rand"
|
|
"sort"
|
|
"testing"
|
|
)
|
|
|
|
func TestHeapMinOrder(t *testing.T) {
|
|
h := NewHeap[int](func(a, b int) bool { return a < b })
|
|
for _, v := range []int{5, 3, 8, 1, 4, 7, 9, 2, 6} {
|
|
h.Push(v)
|
|
}
|
|
var got []int
|
|
for !h.Empty() {
|
|
v, _ := h.Pop()
|
|
got = append(got, v)
|
|
}
|
|
want := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("Pop 顺序[%d] = %d, want %d", i, got[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHeapMaxOrder(t *testing.T) {
|
|
h := NewHeap[int](func(a, b int) bool { return a > b }) // 大顶堆
|
|
for _, v := range []int{5, 3, 8, 1, 4} {
|
|
h.Push(v)
|
|
}
|
|
top, _ := h.Peek()
|
|
if top != 8 {
|
|
t.Fatalf("大顶堆 Peek = %d, want 8", top)
|
|
}
|
|
var got []int
|
|
for !h.Empty() {
|
|
v, _ := h.Pop()
|
|
got = append(got, v)
|
|
}
|
|
want := []int{8, 5, 4, 3, 1}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("大顶堆 Pop[%d] = %d, want %d", i, got[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHeapInit(t *testing.T) {
|
|
h := NewHeap[int](func(a, b int) bool { return a < b })
|
|
data := []int{9, 5, 2, 7, 1, 8, 3}
|
|
// Init 后 h 持有 data 的底层数组,Pop 会原地修改它。
|
|
// 所以 ref 必须在 Init 之前拷贝,避免被破坏。
|
|
ref := make([]int, len(data))
|
|
copy(ref, data)
|
|
sort.Ints(ref)
|
|
|
|
h.Init(data)
|
|
if top, _ := h.Peek(); top != 1 {
|
|
t.Fatalf("Init 后 Peek = %d, want 1", top)
|
|
}
|
|
var got []int
|
|
for !h.Empty() {
|
|
v, _ := h.Pop()
|
|
got = append(got, v)
|
|
}
|
|
for i := range ref {
|
|
if got[i] != ref[i] {
|
|
t.Fatalf("Init+Pop[%d] = %d, want %d", i, got[i], ref[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHeapEmpty(t *testing.T) {
|
|
h := NewHeap[int](func(a, b int) bool { return a < b })
|
|
if _, ok := h.Pop(); ok {
|
|
t.Fatal("空堆 Pop 应返回 false")
|
|
}
|
|
if _, ok := h.Peek(); ok {
|
|
t.Fatal("空堆 Peek 应返回 false")
|
|
}
|
|
}
|
|
|
|
func TestHeapRandomVsSort(t *testing.T) {
|
|
// 随机数据:堆弹出顺序应与排序结果一致。
|
|
h := NewHeap[int](func(a, b int) bool { return a < b })
|
|
rng := rand.New(rand.NewSource(42))
|
|
const N = 2000
|
|
ref := make([]int, N)
|
|
for i := 0; i < N; i++ {
|
|
v := rng.Intn(10000)
|
|
h.Push(v)
|
|
ref[i] = v
|
|
}
|
|
sort.Ints(ref)
|
|
for i := 0; i < N; i++ {
|
|
v, ok := h.Pop()
|
|
if !ok || v != ref[i] {
|
|
t.Fatalf("随机测试[%d] = %d,%v, want %d", i, v, ok, ref[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHeapString(t *testing.T) {
|
|
h := NewHeap[string](func(a, b string) bool { return a < b })
|
|
for _, s := range []string{"banana", "apple", "cherry"} {
|
|
h.Push(s)
|
|
}
|
|
first, _ := h.Pop()
|
|
if first != "apple" {
|
|
t.Fatalf("字符串堆 Pop = %q, want \"apple\"", first)
|
|
}
|
|
}
|