TODO:
This commit is contained in:
parent
6e253bd2d3
commit
36d7f0208b
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user