Compare commits

...

2 Commits

Author SHA1 Message Date
huangsimin
b71ba9ebdd 初步测试, 性能不如添加索引的链表 2019-02-13 11:54:07 +08:00
huangsimin
05bcac44ef 退回最简单的优先链表 2019-02-13 10:52:08 +08:00
2 changed files with 60 additions and 157 deletions

View File

@ -7,30 +7,21 @@ import (
// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
index *Index
indexlimit int
node *Node
size int
comparator utils.Comparator
}
type Index struct {
node *Node
next *Index
nlen int
}
type Node struct {
value interface{}
// prev *Node
next *Node
data []interface{}
left, right, mid int
cap int
size int
isSorted bool
comparator utils.Comparator
}
// NewWithInt compare use int
func NewWithInt() *PriorityQueue {
p := new(PriorityQueue)
p.indexlimit = 10
p.cap = 11
p.mid = 5
p.data = make([]interface{}, p.cap, p.cap)
p.comparator = func(a, b interface{}) int {
if a.(int) > b.(int) {
return 1
@ -41,128 +32,61 @@ 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) + "-"
}
if content != "" {
if content[len(content)-1] == '-' {
content = content[:len(content)-1]
}
}
idxContent := ""
for idx := pq.index; idx != nil; idx = idx.next {
idxContent += spew.Sprint(idx.node.value) + "(" + spew.Sprint(idx.nlen) + ")-"
}
return content + "\n" + idxContent
return "(" + spew.Sprint(pq.data[pq.mid]) + "," + spew.Sprint(pq.size) + ")" + spew.Sprint(pq.Values())
}
func (pq *PriorityQueue) reMakeData() {
var temp []interface{}
if pq.cap <= 1024 {
pq.cap = pq.cap*2 + 1
temp = make([]interface{}, pq.cap, pq.cap)
} else {
pq.cap = pq.cap*5/8*2 + 1
temp = make([]interface{}, pq.cap, pq.cap)
}
pq.mid = (pq.cap - 1) / 2
left := pq.mid - pq.size/2
copy(temp[left:], pq.data[pq.left:pq.right])
pq.left = left
pq.right = pq.left + pq.size
pq.data = temp
}
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
}
// find the node of index to start
idx := pq.index
for {
if idx.next == nil {
break
}
if pq.comparator(v, idx.next.node.value) > 0 {
break
}
idx = idx.next
}
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
if pq.size == 0 {
pq.data[pq.mid] = v
pq.left = pq.mid
pq.right = pq.mid + 1
pq.size = 1
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
} else {
index := new(Index)
index.node = cur
index.nlen = idx.nlen - pq.indexlimit
index.next = idx.next
idx.next = index
idx.nlen = pq.indexlimit
idx = index
i = 0
}
midvalue := pq.data[pq.mid]
if pq.comparator(v, midvalue) > 0 {
if pq.left == 0 {
pq.reMakeData()
}
if pq.comparator(v, cur.next.value) > 0 {
temp := cur.next
cur.next = node
node.next = temp
// node.prev = cur
// temp.prev = node
pq.left--
pq.data[pq.left] = v
} else {
idx.nlen++
// if pq.index.nlen >= pq.indexlimit {
// // 分裂
// }
return
if pq.right == pq.cap {
pq.reMakeData()
}
cur = cur.next
pq.data[pq.right] = v
pq.right++
}
cur.next = node
// node.prev = cur
pq.isSorted = false
pq.size++
idx.nlen++
}
// func (pq *PriorityQueue) Top() (interface{}, bool) {
@ -180,11 +104,11 @@ func (pq *PriorityQueue) Push(v interface{}) {
// return nil, false
// }
// func (pq *PriorityQueue) Values() []interface{} {
// // 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]
// }
func (pq *PriorityQueue) Values() []interface{} {
values := pq.data[pq.left:pq.right]
if !pq.isSorted {
utils.Sort(values, pq.comparator)
pq.isSorted = true
}
return values
}

View File

@ -1,7 +1,6 @@
package plist
import (
"log"
"testing"
"github.com/emirpasic/gods/utils"
@ -11,29 +10,6 @@ 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()
for i := 0; i < 10; i++ {
h1.Push(i)
}
h1.Values()[0] = 3
log.Println(h1)
}
func TestPriorityQueue(t *testing.T) {
p := NewWithInt()
@ -56,6 +32,9 @@ func BenchmarkPriorityQueue(b *testing.B) {
b.N = 100000
for i := 0; i < b.N; i++ {
p.Push(randomdata.Number(0, 100000))
if i%100 == 0 {
p.Values()
}
}
}