基础单索引优先队列
This commit is contained in:
parent
0403bebea4
commit
5d99146aec
|
@ -7,8 +7,11 @@ import (
|
|||
|
||||
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
||||
type PriorityQueue struct {
|
||||
index *Index
|
||||
index *Index
|
||||
|
||||
indexlimit int
|
||||
spanlimit int
|
||||
|
||||
node *Node
|
||||
size int
|
||||
comparator utils.Comparator
|
||||
|
@ -17,12 +20,12 @@ type PriorityQueue struct {
|
|||
type Index struct {
|
||||
node *Node
|
||||
next *Index
|
||||
|
||||
nlen int
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
value interface{}
|
||||
|
||||
// prev *Node
|
||||
next *Node
|
||||
}
|
||||
|
@ -43,14 +46,6 @@ func NewWithInt() *PriorityQueue {
|
|||
func (pq *PriorityQueue) String() string {
|
||||
content := ""
|
||||
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) + "-"
|
||||
}
|
||||
|
||||
|
@ -68,27 +63,10 @@ func (pq *PriorityQueue) String() string {
|
|||
return content + "\n" + idxContent
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Push(v interface{}) {
|
||||
|
||||
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
|
||||
}
|
||||
func (pq *PriorityQueue) findIndexStart(v interface{}) *Index {
|
||||
// find the node of index to start
|
||||
idx := pq.index
|
||||
|
||||
for {
|
||||
|
||||
if idx.next == nil {
|
||||
break
|
||||
}
|
||||
|
@ -99,29 +77,72 @@ func (pq *PriorityQueue) Push(v interface{}) {
|
|||
|
||||
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 := pq.node
|
||||
if pq.comparator(v, pq.node.value) > 0 {
|
||||
pq.node = node
|
||||
node.next = cur
|
||||
|
||||
pq.index.node = pq.node
|
||||
pq.index.nlen++
|
||||
|
||||
// cur.prev = node
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; cur.next != nil; i++ {
|
||||
|
||||
if i >= pq.indexlimit {
|
||||
|
||||
if idx.next != nil && idx.next.nlen < pq.indexlimit {
|
||||
idx.next.nlen += idx.nlen - pq.indexlimit
|
||||
idx.nlen = pq.indexlimit
|
||||
idx.next.node = cur
|
||||
idx = idx.next
|
||||
i = 0
|
||||
} else {
|
||||
index := new(Index)
|
||||
index.node = cur
|
||||
|
@ -133,41 +154,27 @@ func (pq *PriorityQueue) Push(v interface{}) {
|
|||
idx = index
|
||||
i = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if pq.comparator(v, cur.next.value) > 0 {
|
||||
temp := cur.next
|
||||
cur.next = node
|
||||
node.next = temp
|
||||
// node.prev = cur
|
||||
// temp.prev = node
|
||||
|
||||
idx.nlen++
|
||||
|
||||
// if pq.index.nlen >= pq.indexlimit {
|
||||
// // 分裂
|
||||
|
||||
// }
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
cur = cur.next
|
||||
|
||||
}
|
||||
|
||||
cur.next = node
|
||||
|
||||
// node.prev = cur
|
||||
pq.size++
|
||||
idx.nlen++
|
||||
|
||||
}
|
||||
|
||||
// func (pq *PriorityQueue) Top() (interface{}, bool) {
|
||||
// return pq.Get(0)
|
||||
// }
|
||||
func (pq *PriorityQueue) Top() (interface{}, bool) {
|
||||
return pq.Get(0)
|
||||
}
|
||||
|
||||
// func (pq *PriorityQueue) Bottom() (interface{}, bool) {
|
||||
// return pq.Get(pq.right - 1)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package plist
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/emirpasic/gods/utils"
|
||||
|
@ -11,30 +10,30 @@ import (
|
|||
"github.com/emirpasic/gods/trees/binaryheap"
|
||||
)
|
||||
|
||||
type PriorityQ struct {
|
||||
heap *binaryheap.Heap
|
||||
comparator utils.Comparator
|
||||
topk int
|
||||
next *PriorityQ
|
||||
}
|
||||
|
||||
func (pq *PriorityQ) Push(v interface{}) {
|
||||
}
|
||||
|
||||
func TestNPQ(t *testing.T) {
|
||||
h1 := binaryheap.NewWithIntComparator()
|
||||
func TestGetPriorityQueue(t *testing.T) {
|
||||
p := NewWithInt()
|
||||
|
||||
var l []int
|
||||
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()
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
|
|
Loading…
Reference in New Issue
Block a user