From 411281d865d7eaa5586e2e36d418316b9e67ee50 Mon Sep 17 00:00:00 2001 From: huangsimin Date: Thu, 1 Aug 2019 10:07:26 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BC=98=E5=8C=96heap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tree/heap/heap.go | 17 ++++++--------- tree/heap/heap_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/tree/heap/heap.go b/tree/heap/heap.go index b574056..b471dc0 100644 --- a/tree/heap/heap.go +++ b/tree/heap/heap.go @@ -110,40 +110,37 @@ func (h *Heap) Pop() (interface{}, bool) { downvalue := h.elements[h.size] var cidx, c1, c2 int - var cvalue1, cvalue2, cvalue interface{} + var cvalue1, cvalue2 interface{} // down for { cidx = curidx << 1 + c1 = cidx + 1 c2 = cidx + 2 - if c2 < h.size { - cvalue2 = h.elements[c2] - c1 = cidx + 1 + if c2 < h.size { + + cvalue2 = h.elements[c2] cvalue1 = h.elements[c1] if h.Compare(cvalue1, cvalue2) >= 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 { 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..b41f38e 100644 --- a/tree/heap/heap_test.go +++ b/tree/heap/heap_test.go @@ -1,11 +1,60 @@ package heap import ( + "sort" "testing" "github.com/474420502/focus/compare" + "github.com/Pallinder/go-randomdata" ) +func TestHeapGrowSlimming(t *testing.T) { + 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} From 211ab2661c6f6c9e33f5107d7b6b8eb2ae089799 Mon Sep 17 00:00:00 2001 From: huangsimin Date: Thu, 1 Aug 2019 10:36:26 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=9F=90=E6=9D=A1=E4=BB=B6=E4=B8=8B,=20cid?= =?UTF-8?q?x=E6=B2=A1=E6=9C=89=E8=B5=8B=E5=80=BC,=20=E4=B8=8B=E6=A0=87?= =?UTF-8?q?=E5=BF=97=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tree/heap/heap.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tree/heap/heap.go b/tree/heap/heap.go index b471dc0..df876aa 100644 --- a/tree/heap/heap.go +++ b/tree/heap/heap.go @@ -129,10 +129,9 @@ func (h *Heap) Pop() (interface{}, bool) { cidx = c2 } } else { - + cidx = c1 if c1 < h.size { cvalue1 = h.elements[c1] - cidx = c1 } else { break } From f63759645ec002b8d1363a0f94720123abd2c9b9 Mon Sep 17 00:00:00 2001 From: huangsimin Date: Thu, 1 Aug 2019 11:21:17 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0heap=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tree/heap/heap.go | 5 +---- tree/heap/heap_test.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tree/heap/heap.go b/tree/heap/heap.go index df876aa..126fb08 100644 --- a/tree/heap/heap.go +++ b/tree/heap/heap.go @@ -130,12 +130,9 @@ func (h *Heap) Pop() (interface{}, bool) { } } else { cidx = c1 - if c1 < h.size { - cvalue1 = h.elements[c1] - } else { + if c1 >= h.size { break } - } if h.Compare(h.elements[cidx], downvalue) > 0 { diff --git a/tree/heap/heap_test.go b/tree/heap/heap_test.go index b41f38e..b4c90f8 100644 --- a/tree/heap/heap_test.go +++ b/tree/heap/heap_test.go @@ -80,6 +80,28 @@ 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 Int(k1, k2 interface{}) int { From b6fe42de8f87ee4219f0691f9fce89289374e4e1 Mon Sep 17 00:00:00 2001 From: huangsimin Date: Thu, 1 Aug 2019 17:07:28 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=86=8D=E5=BA=A6=E4=BC=98=E5=8C=96heap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tree/heap/heap.go | 7 +--- tree/heap/heap_test.go | 86 +++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/tree/heap/heap.go b/tree/heap/heap.go index 126fb08..e376c30 100644 --- a/tree/heap/heap.go +++ b/tree/heap/heap.go @@ -110,7 +110,6 @@ func (h *Heap) Pop() (interface{}, bool) { downvalue := h.elements[h.size] var cidx, c1, c2 int - var cvalue1, cvalue2 interface{} // down for { cidx = curidx << 1 @@ -119,11 +118,7 @@ func (h *Heap) Pop() (interface{}, bool) { c2 = cidx + 2 if c2 < h.size { - - cvalue2 = h.elements[c2] - cvalue1 = h.elements[c1] - - if h.Compare(cvalue1, cvalue2) >= 0 { + if h.Compare(h.elements[c1], h.elements[c2]) >= 0 { cidx = c1 } else { cidx = c2 diff --git a/tree/heap/heap_test.go b/tree/heap/heap_test.go index b4c90f8..ab4251d 100644 --- a/tree/heap/heap_test.go +++ b/tree/heap/heap_test.go @@ -9,48 +9,52 @@ import ( ) func TestHeapGrowSlimming(t *testing.T) { - 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 + + 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) } - return false - }) + 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() != 100 || h.Empty() { + t.Error("size != 100") } - } - if h.Size() != 0 { - t.Error("size != 0") - } + for i := 0; !h.Empty(); i++ { + v, _ := h.Pop() + if results[i] != v { + t.Error("heap is error") + } + } - h.Put(1) - h.Put(5) - h.Put(2) + if h.Size() != 0 { + t.Error("size != 0") + } - if h.Values()[0] != 5 { - t.Error("top is not equal to 5") - } + h.Put(1) + h.Put(5) + h.Put(2) - h.Clear() - h.Reborn() + if h.Values()[0] != 5 { + t.Error("top is not equal to 5") + } - if !h.Empty() { - t.Error("clear reborn is error") + h.Clear() + h.Reborn() + + if !h.Empty() { + t.Error("clear reborn is error") + } } } @@ -104,6 +108,20 @@ func TestHeapPushTopPop(t *testing.T) { } } +// 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)