基础单索引优先队列

This commit is contained in:
huangsimin 2019-02-13 16:47:11 +08:00
parent 0403bebea4
commit 5d99146aec
2 changed files with 72 additions and 66 deletions

View File

@ -7,8 +7,11 @@ import (
// PriorityQueue 优先队列 适合数据量不大, 加索引 // PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct { type PriorityQueue struct {
index *Index index *Index
indexlimit int indexlimit int
spanlimit int
node *Node node *Node
size int size int
comparator utils.Comparator comparator utils.Comparator
@ -17,12 +20,12 @@ type PriorityQueue struct {
type Index struct { type Index struct {
node *Node node *Node
next *Index next *Index
nlen int nlen int
} }
type Node struct { type Node struct {
value interface{} value interface{}
// prev *Node // prev *Node
next *Node next *Node
} }
@ -43,14 +46,6 @@ func NewWithInt() *PriorityQueue {
func (pq *PriorityQueue) String() string { func (pq *PriorityQueue) String() string {
content := "" content := ""
for cur := pq.node; cur != nil; cur = cur.next { for cur := pq.node; cur != nil; cur = cur.next {
// var prevcontent string
// if cur.prev != nil {
// prevcontent = "(" + spew.Sprint(cur.prev.value) + "<-)"
// } else {
// prevcontent = "(nil)"
// }
// content += spew.Sprint(cur.value) + prevcontent + "-"
content += spew.Sprint(cur.value) + "-" content += spew.Sprint(cur.value) + "-"
} }
@ -68,27 +63,10 @@ func (pq *PriorityQueue) String() string {
return content + "\n" + idxContent return content + "\n" + idxContent
} }
func (pq *PriorityQueue) Push(v interface{}) { func (pq *PriorityQueue) findIndexStart(v interface{}) *Index {
node := new(Node)
node.value = v
if pq.node == nil {
//创建索引
index := new(Index)
index.nlen = 1
index.node = node
pq.index = index
pq.node = node
return
}
// find the node of index to start // find the node of index to start
idx := pq.index idx := pq.index
for { for {
if idx.next == nil { if idx.next == nil {
break break
} }
@ -99,29 +77,72 @@ func (pq *PriorityQueue) Push(v interface{}) {
idx = idx.next idx = idx.next
} }
return idx
}
func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
if index < 0 || index >= pq.size {
return nil, false
}
idx := pq.index
movesize := index
for {
if movesize-idx.nlen <= 0 {
break
} else {
movesize -= idx.nlen
idx = idx.next
}
}
cur := idx.node
for movesize > 0 {
movesize--
cur = cur.next
}
return cur.value, true
}
func (pq *PriorityQueue) Push(v interface{}) {
node := new(Node)
node.value = v
pq.size++
if pq.node == nil {
//创建索引
index := new(Index)
index.nlen = 1
index.node = node
pq.index = index
pq.node = node
return
}
// find the node of index to start
idx := pq.findIndexStart(v)
cur := idx.node cur := idx.node
//cur := pq.node
if pq.comparator(v, pq.node.value) > 0 { if pq.comparator(v, pq.node.value) > 0 {
pq.node = node pq.node = node
node.next = cur node.next = cur
pq.index.node = pq.node pq.index.node = pq.node
pq.index.nlen++ pq.index.nlen++
// cur.prev = node
return return
} }
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 {
idx.next.nlen += idx.nlen - pq.indexlimit idx.next.nlen += idx.nlen - pq.indexlimit
idx.nlen = pq.indexlimit idx.nlen = pq.indexlimit
idx.next.node = cur idx.next.node = cur
idx = idx.next
i = 0
} else { } else {
index := new(Index) index := new(Index)
index.node = cur index.node = cur
@ -133,41 +154,27 @@ func (pq *PriorityQueue) Push(v interface{}) {
idx = index idx = index
i = 0 i = 0
} }
} }
if pq.comparator(v, cur.next.value) > 0 { if pq.comparator(v, cur.next.value) > 0 {
temp := cur.next temp := cur.next
cur.next = node cur.next = node
node.next = temp node.next = temp
// node.prev = cur
// temp.prev = node
idx.nlen++ idx.nlen++
// if pq.index.nlen >= pq.indexlimit {
// // 分裂
// }
return return
} }
cur = cur.next cur = cur.next
} }
cur.next = node cur.next = node
// node.prev = cur
pq.size++
idx.nlen++ idx.nlen++
} }
// func (pq *PriorityQueue) Top() (interface{}, bool) { func (pq *PriorityQueue) Top() (interface{}, bool) {
// return pq.Get(0) return pq.Get(0)
// } }
// func (pq *PriorityQueue) Bottom() (interface{}, bool) { // func (pq *PriorityQueue) Bottom() (interface{}, bool) {
// return pq.Get(pq.right - 1) // return pq.Get(pq.right - 1)

View File

@ -1,7 +1,6 @@
package plist package plist
import ( import (
"log"
"testing" "testing"
"github.com/emirpasic/gods/utils" "github.com/emirpasic/gods/utils"
@ -11,30 +10,30 @@ import (
"github.com/emirpasic/gods/trees/binaryheap" "github.com/emirpasic/gods/trees/binaryheap"
) )
type PriorityQ struct { func TestGetPriorityQueue(t *testing.T) {
heap *binaryheap.Heap p := NewWithInt()
comparator utils.Comparator
topk int
next *PriorityQ
}
func (pq *PriorityQ) Push(v interface{}) {
}
func TestNPQ(t *testing.T) {
h1 := binaryheap.NewWithIntComparator()
var l []int
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
h1.Push(i) l = append(l, randomdata.Number(0, 10000))
} }
h1.Values()[0] = 3 for _, v := range l {
p.Push(v)
t.Log(p.String())
}
log.Println(h1) t.Error(l)
t.Error(p.String())
for _, i := range []int{-1, 0, p.size / 2, p.size - 1, p.size} {
v, ok := p.Get(i)
t.Error(i, v, ok)
}
} }
func TestPriorityQueue(t *testing.T) { func TestPustPriorityQueue(t *testing.T) {
p := NewWithInt() p := NewWithInt()
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {