From 6e253bd2d30f12be96b503e39458181107f68487 Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Fri, 1 Feb 2019 03:57:40 +0800 Subject: [PATCH] TODO: PQ finish task --- priority_queue/priority_queue.go | 93 ++++++++++++++++----------- priority_queue/priority_queue_test.go | 3 +- 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/priority_queue/priority_queue.go b/priority_queue/priority_queue.go index 8b42426..0b8c47b 100644 --- a/priority_queue/priority_queue.go +++ b/priority_queue/priority_queue.go @@ -10,8 +10,7 @@ type PriorityQueue struct { datas []interface{} size int comparator utils.Comparator - isLeftSorted bool - isRightSorted bool + isSorted bool } // NewWithInt compare use int @@ -54,6 +53,26 @@ func (pq *PriorityQueue) reMakeMemory() { } +func (pq *PriorityQueue) search(v interface{}) int { + left := pq.left + right := pq.right + + for left < right-1 { + mid := (left + right) / 2 // 4 10 7 10 8 10 9 10 | 4 10 4 7 4 5 + if pq.comparator(v, pq.datas[mid]) > 0 { + left = mid + } else { + right = mid + } + } + + if pq.comparator(v, pq.datas[left]) > 0 { + return left + 1 + } else { + return left + } +} + func (pq *PriorityQueue) Push(v interface{}) { if pq.size == 0 { @@ -65,46 +84,51 @@ func (pq *PriorityQueue) Push(v interface{}) { } else { - if pq.comparator(v, pq.datas[pq.mid]) > 0 { + // if pq.comparator(v, pq.datas[pq.mid]) > 0 { + // if pq.right >= len(pq.datas) { + // // 重建 datas + // pq.reMakeMemory() + // } + + // pq.datas[pq.right] = v + // pq.right++ + + // } else { + + // if pq.left-1 < 0 { + // // 重建 datas + // pq.reMakeMemory() + // } + // pq.left-- + // pq.datas[pq.left] = v + + // } + + idx := pq.search(v) + if idx > pq.mid { if pq.right >= len(pq.datas) { - // 重建 datas pq.reMakeMemory() } - pq.datas[pq.right] = v - pq.right++ - - if pq.isRightSorted { - pq.isRightSorted = false - } - - } else { - - if pq.left-1 < 0 { - // 重建 datas - pq.reMakeMemory() - } - pq.left-- - pq.datas[pq.left] = v - - if pq.isLeftSorted { - pq.isLeftSorted = false - } } } + pq.size++ + if pq.isSorted { + pq.isSorted = false + } } -func (pq *PriorityQueue) PopTop() (interface{}, bool) { +// func (pq *PriorityQueue) PopTop() (interface{}, bool) { - return v, isok -} +// return v, isok +// } -func (pq *PriorityQueue) PopBottom() (interface{}, bool) { +// func (pq *PriorityQueue) PopBottom() (interface{}, bool) { - return v, isok -} +// return v, isok +// } func (pq *PriorityQueue) Top() (interface{}, bool) { return pq.Get(0) @@ -124,14 +148,9 @@ func (pq *PriorityQueue) Get(index int) (interface{}, bool) { func (pq *PriorityQueue) Values() []interface{} { values := pq.datas[pq.left:pq.right] - if !pq.isLeftSorted { - utils.Sort(values[0:pq.size/2], pq.comparator) - pq.isLeftSorted = true - } - - if !pq.isRightSorted { - utils.Sort(values[pq.size/2:], pq.comparator) - pq.isRightSorted = true + if !pq.isSorted { + utils.Sort(values, pq.comparator) + pq.isSorted = true } return values diff --git a/priority_queue/priority_queue_test.go b/priority_queue/priority_queue_test.go index f65422a..758260b 100644 --- a/priority_queue/priority_queue_test.go +++ b/priority_queue/priority_queue_test.go @@ -19,6 +19,7 @@ func TestPriorityQueue(t *testing.T) { t.Error(p.Values()) t.Error(p.datas, p.size, len(p.Values())) + t.Error(p.search(1000000)) for _, idx := range []int{5, 0, 21, 19} { t.Error(p.Get(idx)) @@ -31,7 +32,7 @@ func BenchmarkPriorityQueue10(b *testing.B) { for i := 0; i < b.N; i++ { p.Push(randomdata.Number(0, 100000)) - if i%10 == 0 { + if i%100 == 0 { p.Values() } }