TODO: 完善avl索引

This commit is contained in:
huangsimin 2019-02-13 18:02:01 +08:00
parent 5d99146aec
commit cd40d47a3c
2 changed files with 62 additions and 15 deletions

View File

@ -2,28 +2,20 @@ package plist
import ( import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/trees/avltree"
"github.com/emirpasic/gods/utils" "github.com/emirpasic/gods/utils"
) )
// PriorityQueue 优先队列 适合数据量不大, 加索引 // PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct { type PriorityQueue struct {
index *Index avlIndex *avltree.Tree
indexlimit int indexlimit int
spanlimit int
node *Node node *Node
size int size int
comparator utils.Comparator comparator utils.Comparator
} }
type Index struct {
node *Node
next *Index
nlen int
}
type Node struct { type Node struct {
value interface{} value interface{}
// prev *Node // prev *Node
@ -33,13 +25,17 @@ type Node struct {
// NewWithInt compare use int // NewWithInt compare use int
func NewWithInt() *PriorityQueue { func NewWithInt() *PriorityQueue {
p := new(PriorityQueue) p := new(PriorityQueue)
p.indexlimit = 10
p.comparator = func(a, b interface{}) int { p.comparator = func(a, b interface{}) int {
if a.(int) > b.(int) { if a.(int) > b.(int) {
return 1 return 1
} }
return -1 return -1
} }
p.indexlimit = 10
p.avlIndex = avltree.NewWith(p.comparator)
return p return p
} }
@ -135,6 +131,8 @@ func (pq *PriorityQueue) Push(v interface{}) {
} }
for i := 0; cur.next != nil; i++ { for i := 0; cur.next != nil; i++ {
// 分裂和整理索引
if i >= pq.indexlimit { if i >= pq.indexlimit {
if idx.next != nil && idx.next.nlen < pq.indexlimit { if idx.next != nil && idx.next.nlen < pq.indexlimit {
@ -142,7 +140,6 @@ func (pq *PriorityQueue) Push(v interface{}) {
idx.nlen = pq.indexlimit idx.nlen = pq.indexlimit
idx.next.node = cur idx.next.node = cur
idx = idx.next idx = idx.next
i = 0
} else { } else {
index := new(Index) index := new(Index)
index.node = cur index.node = cur
@ -152,8 +149,9 @@ func (pq *PriorityQueue) Push(v interface{}) {
idx.next = index idx.next = index
idx.nlen = pq.indexlimit idx.nlen = pq.indexlimit
idx = index idx = index
i = 0
} }
i = 0
} }
if pq.comparator(v, cur.next.value) > 0 { if pq.comparator(v, cur.next.value) > 0 {

View File

@ -3,6 +3,8 @@ package plist
import ( import (
"testing" "testing"
"github.com/emirpasic/gods/trees/avltree"
"github.com/emirpasic/gods/utils" "github.com/emirpasic/gods/utils"
"github.com/Pallinder/go-randomdata" "github.com/Pallinder/go-randomdata"
@ -44,7 +46,7 @@ func TestPustPriorityQueue(t *testing.T) {
t.Error(p.String()) t.Error(p.String())
} }
func BenchmarkPriorityQueue(b *testing.B) { func BenchmarkPriorityQueuePush(b *testing.B) {
p := NewWithInt() p := NewWithInt()
// for i := 0; i < 10000; i++ { // for i := 0; i < 10000; i++ {
@ -52,14 +54,61 @@ func BenchmarkPriorityQueue(b *testing.B) {
// // p.Values() // // p.Values()
// } // }
b.N = 100000 b.N = 10000
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
p.Push(randomdata.Number(0, 100000)) p.Push(randomdata.Number(0, 100000))
} }
} }
func BenchmarkPriorityQueueGet(b *testing.B) {
p := NewWithInt()
for i := 0; i < 10000; i++ {
p.Push(randomdata.Number(0, 100000))
// p.Values()
}
b.StartTimer()
b.N = 100000
for i := 0; i < b.N; i++ {
p.Get(randomdata.Number(0, 10000))
}
b.StopTimer()
}
func TestAVL(t *testing.T) {
avl := avltree.NewWithIntComparator()
for i := 0; i < 10; i++ {
v := randomdata.Number(0, 10)
avl.Put(v, v)
}
t.Error(avl.Values())
f, ok := avl.Ceiling(100)
t.Error(f, ok)
t.Error(f.Next().Value)
}
func BenchmarkAVL(b *testing.B) {
avl := avltree.NewWithIntComparator()
b.N = 1000000
b.StartTimer()
for i := 0; i < b.N; i++ {
v := randomdata.Number(0, 100000000)
avl.Put(v, v)
}
for i := 0; i < b.N; i++ {
avl.Get(i)
}
b.StopTimer()
}
func TestHeap(t *testing.T) { func TestHeap(t *testing.T) {
heap := binaryheap.NewWithIntComparator() heap := binaryheap.NewWithIntComparator()
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {