diff --git a/tree/heap/heap.go b/tree/heap/heap.go index b574056..e376c30 100644 --- a/tree/heap/heap.go +++ b/tree/heap/heap.go @@ -110,40 +110,28 @@ func (h *Heap) Pop() (interface{}, bool) { downvalue := h.elements[h.size] var cidx, c1, c2 int - var cvalue1, cvalue2, cvalue interface{} // down for { cidx = curidx << 1 + c1 = cidx + 1 c2 = cidx + 2 + if c2 < h.size { - cvalue2 = h.elements[c2] - - c1 = cidx + 1 - cvalue1 = h.elements[c1] - - if h.Compare(cvalue1, cvalue2) >= 0 { + if h.Compare(h.elements[c1], h.elements[c2]) >= 0 { cidx = c1 - cvalue = cvalue1 } else { cidx = c2 - cvalue = cvalue2 } } else { - - c1 = cidx + 1 - if c1 < h.size { - cvalue1 = h.elements[c1] - cidx = c1 - cvalue = cvalue1 - } else { + cidx = c1 + if c1 >= h.size { break } - } - if h.Compare(cvalue, downvalue) > 0 { - h.elements[curidx] = cvalue + if h.Compare(h.elements[cidx], downvalue) > 0 { + h.elements[curidx] = h.elements[cidx] curidx = cidx } else { break diff --git a/tree/heap/heap_test.go b/tree/heap/heap_test.go index 5d085df..ab4251d 100644 --- a/tree/heap/heap_test.go +++ b/tree/heap/heap_test.go @@ -1,11 +1,64 @@ package heap import ( + "sort" "testing" "github.com/474420502/focus/compare" + "github.com/Pallinder/go-randomdata" ) +func TestHeapGrowSlimming(t *testing.T) { + + for ii := 0; ii < 1000; ii++ { + + h := New(compare.Int) + var results []int + for i := 0; i < 100; i++ { + v := randomdata.Number(0, 100) + results = append(results, v) + h.Put(v) + } + sort.Slice(results, func(i, j int) bool { + if results[i] > results[j] { + return true + } + return false + }) + + if h.Size() != 100 || h.Empty() { + t.Error("size != 100") + } + + for i := 0; !h.Empty(); i++ { + v, _ := h.Pop() + if results[i] != v { + t.Error("heap is error") + } + } + + if h.Size() != 0 { + t.Error("size != 0") + } + + h.Put(1) + h.Put(5) + h.Put(2) + + if h.Values()[0] != 5 { + t.Error("top is not equal to 5") + } + + h.Clear() + h.Reborn() + + if !h.Empty() { + t.Error("clear reborn is error") + } + } + +} + func TestHeapPushTopPop(t *testing.T) { h := New(compare.Int) l := []int{9, 5, 15, 2, 3} @@ -31,8 +84,44 @@ func TestHeapPushTopPop(t *testing.T) { if h.Size() != 0 { t.Error("heap size is not equals to zero") } + + h.Clear() + + l = []int{3, 5, 2, 7, 1} + + for _, v := range l { + h.Put(v) + } + + sort.Slice(l, func(i, j int) bool { + if l[i] > l[j] { + return true + } + return false + }) + + for i := 0; !h.Empty(); i++ { + v, _ := h.Pop() + if l[i] != v { + t.Error("heap is error") + } + } } +// func BenchmarkPush(b *testing.B) { +// h := New(compare.Int) +// b.N = 40000000 +// var results []int +// for i := 0; i < b.N; i++ { +// results = append(results, randomdata.Number(0, 1000000000)) +// } + +// b.ResetTimer() +// for _, v := range results { +// h.Put(v) +// } +// } + // func Int(k1, k2 interface{}) int { // c1 := k1.(int) // c2 := k2.(int)