This commit is contained in:
eson 2019-02-25 03:08:47 +08:00
parent 0fb5a2ca4a
commit 5c3828542b
3 changed files with 34 additions and 184 deletions

View File

@ -1,58 +0,0 @@
package plist
import (
"github.com/davecgh/go-spew/spew"
)
// Node 节点结构
type Node struct {
next *Node
value interface{}
}
// PriorityList
type PriorityList struct {
size int
head *Node
}
// New a node
func New() *PriorityList {
p := new(PriorityList)
return p
}
// String 展示需要的
func (pl *PriorityList) String() string {
content := ""
for cur := pl.head; cur != nil; cur = cur.next {
content += spew.Sprint(cur.value) + "-"
}
if content != "" && content[len(content)-1] == '-' {
content = content[:len(content)-1]
}
return content
}
// insert 插入值
func (pl *PriorityList) nodeInsert(cur *Node, value interface{}) {
if cur == nil {
temp := pl.head
pl.head = &Node{value: value}
pl.head.next = temp
return
}
temp := cur.next
cur.next = &Node{value: value}
cur.next.next = temp
}
// Size 长度
func (pl *PriorityList) Size() int {
return pl.size
}

View File

@ -1,41 +1,33 @@
package plist
import (
"errors"
"log"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/trees/avltree"
"github.com/emirpasic/gods/trees/binaryheap"
"github.com/emirpasic/gods/utils"
)
// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
avl *avltree.Tree
heaps []*binaryheap.Heap
heapsCap int
cursor int
splitlimit int
size int
comparator utils.Comparator
splitlimit int
}
func (pq *PriorityQueue) String() string {
content := ""
iter := pq.avl.Iterator()
for !iter.Last() {
iter.Next()
}
for iter.Prev() {
pl := iter.Value().(*PriorityList)
cur := pl.head
for cur != nil {
content += spew.Sprint(cur.value) + "-"
cur = cur.next
}
content = strings.TrimRight(content, "-")
content += " "
for i := pq.cursor; i < pq.heapsCap; i++ {
content += spew.Sprint(pq.heaps[i].Values()) + "--"
}
return content
@ -43,6 +35,11 @@ func (pq *PriorityQueue) String() string {
func NewWithIntComparator() *PriorityQueue {
pq := new(PriorityQueue)
pq.splitlimit = 20
pq.heapsCap = 10
pq.heaps = make([]*binaryheap.Heap, pq.heapsCap, pq.heapsCap)
pq.cursor = pq.heapsCap - 1
pq.comparator = func(v1, v2 interface{}) int {
if v1.(int) > v2.(int) {
return 1
@ -51,78 +48,35 @@ func NewWithIntComparator() *PriorityQueue {
}
return 0
}
pq.avl = avltree.NewWith(pq.comparator)
pq.splitlimit = 8
pq.size = 0
pq.heaps[pq.cursor] = binaryheap.NewWith(pq.comparator)
return pq
}
func (pq *PriorityQueue) Push(value interface{}) {
var pl *PriorityList
pq.size++
defer func() {
if pl.size >= pq.splitlimit {
moveIndex := pl.size / 2
cur := pl.head
for i := 1; i < moveIndex; i++ {
cur = cur.next
curheap := pq.heaps[pq.cursor]
log.Println(pq.heaps)
if curheap.Size() >= pq.splitlimit {
if pq.cursor == 0 {
// remake
}
pq.cursor--
heap := binaryheap.NewWith(pq.comparator)
heap.Push(value)
for i := 0; i < pq.splitlimit/2-1; i++ {
v, ok := curheap.Pop()
if !ok {
panic(errors.New("size is error?"))
}
log.Println("pq:", pq.String())
temp := cur.next
cur.next = nil
plsp := &PriorityList{}
plsp.head = temp
plsp.size = pl.size - moveIndex
pl.size = moveIndex
pq.avl.Put(plsp.head.value, plsp)
log.Println("list:", pl.head.value, pl.String())
log.Println("list:", plsp.head.value, plsp.String())
log.Println("pq:", pq.avl.Values())
log.Println("pq:", pq.String(), "\n----------")
heap.Push(v)
}
}()
floor, ok := pq.avl.Floor(value)
if ok {
pl = floor.Value.(*PriorityList)
cur := pl.head
pl.size++
if pq.comparator(value, cur.value) > 0 {
temp := pl.head
pl.head = &Node{value: value}
pl.head.next = temp
return
}
for cur.next != nil {
if pq.comparator(value, cur.next.value) >= 0 {
temp := cur.next
cur.next = &Node{value: value}
cur.next.next = temp
return
}
cur = cur.next
}
// next == nil
cur.next = &Node{value: value}
return
pq.heaps[pq.cursor] = heap
} else {
curheap.Push(value)
}
pl = &PriorityList{}
pl.head = &Node{value: value}
pl.size++
pq.avl.Put(pl.head.value, pl)
return
}

View File

@ -12,22 +12,6 @@ import (
"github.com/emirpasic/gods/trees/binaryheap"
)
func TestPList(t *testing.T) {
pl := &PriorityList{}
for i := 0; i < 10; i++ {
pl.nodeInsert(nil, randomdata.Number(0, 10))
}
t.Error(pl.String())
cur := pl.head
for i := 0; i < 5; i++ {
cur = cur.next
}
pl.nodeInsert(cur, 11)
t.Error(pl.String())
}
func TestPQ(t *testing.T) {
var l []int
@ -48,40 +32,10 @@ func TestPQ(t *testing.T) {
}
func BenchmarkPQ(b *testing.B) {
pq := NewWithIntComparator()
b.N = 1000000
for i := b.N; i > 0; i-- {
pq.Push(i)
}
iter := pq.avl.Iterator()
iter.Next()
pl := iter.Value().(*PriorityList)
b.Log(pq.size, pq.avl.Size(), pl.Size(), pl.head)
b.Log(pl.head.value)
if pl.head.next != nil {
b.Log(pl.head.next.value)
}
// b.Log("all:", pq.avl.Size(), pq.avl.Values())
}
func BenchmarkPList(b *testing.B) {
for i := 0; i < b.N; i++ {
pl := &PriorityList{}
for i2 := 0; i2 < 5; i2++ {
cur := pl.head
for n := 0; n < i2; n++ {
cur = cur.next
}
pl.nodeInsert(cur, i2)
}
}
}
func TestAvl(t *testing.T) {
comparator := func(v1, v2 interface{}) int {