初步测试, 性能不如添加索引的链表
This commit is contained in:
parent
05bcac44ef
commit
b71ba9ebdd
|
@ -7,30 +7,21 @@ import (
|
||||||
|
|
||||||
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
||||||
type PriorityQueue struct {
|
type PriorityQueue struct {
|
||||||
index *Index
|
data []interface{}
|
||||||
indexlimit int
|
left, right, mid int
|
||||||
node *Node
|
cap int
|
||||||
size int
|
size int
|
||||||
comparator utils.Comparator
|
isSorted bool
|
||||||
}
|
comparator utils.Comparator
|
||||||
|
|
||||||
type Index struct {
|
|
||||||
node *Node
|
|
||||||
next *Index
|
|
||||||
nlen int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Node struct {
|
|
||||||
value interface{}
|
|
||||||
|
|
||||||
// prev *Node
|
|
||||||
next *Node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWithInt compare use int
|
// NewWithInt compare use int
|
||||||
func NewWithInt() *PriorityQueue {
|
func NewWithInt() *PriorityQueue {
|
||||||
p := new(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 {
|
p.comparator = func(a, b interface{}) int {
|
||||||
if a.(int) > b.(int) {
|
if a.(int) > b.(int) {
|
||||||
return 1
|
return 1
|
||||||
|
@ -41,74 +32,61 @@ func NewWithInt() *PriorityQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pq *PriorityQueue) String() string {
|
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 + "-"
|
return "(" + spew.Sprint(pq.data[pq.mid]) + "," + spew.Sprint(pq.size) + ")" + spew.Sprint(pq.Values())
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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{}) {
|
func (pq *PriorityQueue) Push(v interface{}) {
|
||||||
|
|
||||||
node := new(Node)
|
if pq.size == 0 {
|
||||||
node.value = v
|
pq.data[pq.mid] = v
|
||||||
pq.size++
|
pq.left = pq.mid
|
||||||
|
pq.right = pq.mid + 1
|
||||||
if pq.node == nil {
|
pq.size = 1
|
||||||
//创建索引
|
|
||||||
pq.node = node
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cur := pq.node
|
midvalue := pq.data[pq.mid]
|
||||||
|
if pq.comparator(v, midvalue) > 0 {
|
||||||
//cur := pq.node
|
if pq.left == 0 {
|
||||||
if pq.comparator(v, pq.node.value) > 0 {
|
pq.reMakeData()
|
||||||
pq.node = node
|
|
||||||
node.next = cur
|
|
||||||
// cur.prev = node
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; cur.next != nil; i++ {
|
|
||||||
|
|
||||||
if pq.comparator(v, cur.next.value) > 0 {
|
|
||||||
temp := cur.next
|
|
||||||
cur.next = node
|
|
||||||
node.next = temp
|
|
||||||
// node.prev = cur
|
|
||||||
// temp.prev = node
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = cur.next
|
pq.left--
|
||||||
|
pq.data[pq.left] = v
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if pq.right == pq.cap {
|
||||||
|
pq.reMakeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
pq.data[pq.right] = v
|
||||||
|
pq.right++
|
||||||
}
|
}
|
||||||
|
|
||||||
cur.next = node
|
pq.isSorted = false
|
||||||
|
pq.size++
|
||||||
// node.prev = cur
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (pq *PriorityQueue) Top() (interface{}, bool) {
|
// func (pq *PriorityQueue) Top() (interface{}, bool) {
|
||||||
|
@ -126,11 +104,11 @@ func (pq *PriorityQueue) Push(v interface{}) {
|
||||||
// return nil, false
|
// return nil, false
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (pq *PriorityQueue) Values() []interface{} {
|
func (pq *PriorityQueue) Values() []interface{} {
|
||||||
// // values := pq.datas[pq.left:pq.right]
|
values := pq.data[pq.left:pq.right]
|
||||||
// // if !pq.isSorted {
|
if !pq.isSorted {
|
||||||
// // utils.Sort(values, pq.comparator)
|
utils.Sort(values, pq.comparator)
|
||||||
// // pq.isSorted = true
|
pq.isSorted = true
|
||||||
// // }
|
}
|
||||||
// return pq.datas[pq.left:pq.right]
|
return values
|
||||||
// }
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package plist
|
package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
|
@ -11,29 +10,6 @@ import (
|
||||||
"github.com/emirpasic/gods/trees/binaryheap"
|
"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) {
|
func TestPriorityQueue(t *testing.T) {
|
||||||
p := NewWithInt()
|
p := NewWithInt()
|
||||||
|
|
||||||
|
@ -56,6 +32,9 @@ func BenchmarkPriorityQueue(b *testing.B) {
|
||||||
b.N = 100000
|
b.N = 100000
|
||||||
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))
|
||||||
|
if i%100 == 0 {
|
||||||
|
p.Values()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user