diff --git a/priority_queue/priority_queue.go b/priority_queue/priority_queue.go index 0b8c47b..59d133d 100644 --- a/priority_queue/priority_queue.go +++ b/priority_queue/priority_queue.go @@ -1,6 +1,8 @@ package plist import ( + "log" + "github.com/emirpasic/gods/utils" ) @@ -43,30 +45,38 @@ func (pq *PriorityQueue) reMakeMemory() { temp := make([]interface{}, capacity) mid := capacity / 2 - left := mid - pq.size/2 + left := mid - pq.size/2 - 1 - copy(temp[left:], pq.datas[pq.left:pq.right]) + x := pq.datas + copy(temp[left+1:], pq.datas[pq.left+1:pq.right]) pq.datas = temp pq.left = left pq.mid = mid pq.right = pq.size + pq.left + log.Println(x, pq.datas, pq.left, pq.right) + } func (pq *PriorityQueue) search(v interface{}) int { - left := pq.left - right := pq.right + // left := pq.left + // right := pq.right + + data := pq.datas[pq.left+1 : pq.right] + left := 0 + mid := 0 + right := len(data) 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 { + mid = (left + right) / 2 // 4 10 7 10 8 10 9 10 | 4 10 4 7 4 5 + if pq.comparator(v, data[mid]) > 0 { left = mid } else { right = mid } } - if pq.comparator(v, pq.datas[left]) > 0 { + if pq.comparator(v, data[left]) > 0 { return left + 1 } else { return left @@ -75,13 +85,27 @@ func (pq *PriorityQueue) search(v interface{}) int { func (pq *PriorityQueue) Push(v interface{}) { + defer func() { + if err := recover(); err != nil { + + log.Println(pq.datas) + log.Println(pq.left, pq.right, pq.size) + log.Panic(err) + + } + }() + if pq.size == 0 { + pq.mid = len(pq.datas) / 2 - pq.left = pq.mid + pq.left = pq.mid - 1 pq.right = pq.mid + 1 pq.datas[pq.mid] = v + log.Println(pq.datas) + log.Println(pq.left) + } else { // if pq.comparator(v, pq.datas[pq.mid]) > 0 { @@ -102,22 +126,44 @@ func (pq *PriorityQueue) Push(v interface{}) { // } // pq.left-- // pq.datas[pq.left] = v - // } idx := pq.search(v) - if idx > pq.mid { + log.Println("idx:", idx) + if idx > pq.size/2 { + if pq.right >= len(pq.datas) { pq.reMakeMemory() } + offset := pq.left + 1 + idx + copy(pq.datas[offset+1:], pq.datas[offset:pq.right]) + pq.datas[offset] = v + pq.right++ + // log.Println("right: ", pq.datas) + + } else { + + if pq.left < 0 { + // 重建 datas + pq.reMakeMemory() + } + + offset := pq.left + 1 + idx + copy(pq.datas[pq.left:], pq.datas[pq.left+1:offset]) + pq.datas[offset] = v + pq.left-- + + // log.Println("left: ", pq.datas) } + } pq.size++ - if pq.isSorted { - pq.isSorted = false - } + log.Println("push:", pq.datas) + // if pq.isSorted { + // pq.isSorted = false + // } } // func (pq *PriorityQueue) PopTop() (interface{}, bool) { @@ -146,12 +192,10 @@ func (pq *PriorityQueue) Get(index int) (interface{}, bool) { } func (pq *PriorityQueue) Values() []interface{} { - values := pq.datas[pq.left:pq.right] - - if !pq.isSorted { - utils.Sort(values, pq.comparator) - pq.isSorted = true - } - - return values + // values := pq.datas[pq.left:pq.right] + // if !pq.isSorted { + // utils.Sort(values, pq.comparator) + // pq.isSorted = true + // } + return pq.datas[pq.left:pq.right] } diff --git a/priority_queue/priority_queue_test.go b/priority_queue/priority_queue_test.go index 758260b..be034a1 100644 --- a/priority_queue/priority_queue_test.go +++ b/priority_queue/priority_queue_test.go @@ -3,6 +3,8 @@ package plist import ( "testing" + "github.com/davecgh/go-spew/spew" + "github.com/emirpasic/gods/utils" "github.com/Pallinder/go-randomdata" @@ -17,9 +19,30 @@ func TestPriorityQueue(t *testing.T) { p.Push(randomdata.Number(0, 10000)) } - t.Error(p.Values()) + data := p.Values() + t.Error(data) + + content := "" + last := 0 + for i := 0; i < len(data); i++ { + if i == 0 { + content += "\n" + } else if i%5 == 0 { + content += spew.Sprintln(data[last:i]) + last = i + } + } + content += spew.Sprintln(data[last:]) + t.Error(content) + + lleft := p.search(0) + lmid := p.search(5000) + lright := p.search(10000) + + t.Error(lleft, lmid, lright) + t.Error(p.left+lleft, p.left+lmid, p.left+lright) + 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)) @@ -27,17 +50,18 @@ func TestPriorityQueue(t *testing.T) { } -func BenchmarkPriorityQueue10(b *testing.B) { +func BenchmarkPriorityQueue(b *testing.B) { p := NewWithInt() + // for i := 0; i < 100000; i++ { + // p.Push(randomdata.Number(0, 100000)) + // // p.Values() + // } + for i := 0; i < b.N; i++ { p.Push(randomdata.Number(0, 100000)) - if i%100 == 0 { - p.Values() - } } - // t.Error(p.String()) } func TestHeap(t *testing.T) {