TODO: 设计出几种不同优先队列的架构.
This commit is contained in:
parent
ad18004bc2
commit
055113962d
|
@ -1,147 +1,41 @@
|
||||||
package plist
|
package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"474420502.top/eson/structure"
|
"github.com/emirpasic/gods/lists/arraylist"
|
||||||
|
"github.com/emirpasic/gods/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodeList struct {
|
// PriorityQueue 优先队列
|
||||||
head, tail *Node
|
type PriorityQueue struct {
|
||||||
|
array arraylist.List
|
||||||
|
comparator utils.Comparator
|
||||||
|
isSorted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node 节点结构
|
// NewWithInt compare use int
|
||||||
type Node struct {
|
func NewWithInt() *PriorityQueue {
|
||||||
prev, next *Node
|
p := new(PriorityQueue)
|
||||||
structure.NValue
|
p.comparator = func(a, b interface{}) int {
|
||||||
}
|
if a.(int) > b.(int) {
|
||||||
|
return 1
|
||||||
// PriorityList 跳表
|
}
|
||||||
type PriorityList struct {
|
return -1
|
||||||
size int
|
}
|
||||||
compare func(v1, v2 interface{}) int
|
|
||||||
level *LevelNode
|
|
||||||
}
|
|
||||||
|
|
||||||
type LevelSize struct {
|
|
||||||
size int
|
|
||||||
}
|
|
||||||
|
|
||||||
// LevelNode 层级列表
|
|
||||||
type LevelNode struct {
|
|
||||||
node *Node
|
|
||||||
prev *LevelNode
|
|
||||||
next *LevelNode
|
|
||||||
sub interface{}
|
|
||||||
lsize *LevelSize
|
|
||||||
level int
|
|
||||||
}
|
|
||||||
|
|
||||||
// New a node
|
|
||||||
func New() *PriorityList {
|
|
||||||
p := new(PriorityList)
|
|
||||||
p.level = new(LevelNode)
|
|
||||||
p.level.lsize = new(LevelSize)
|
|
||||||
p.level.lsize.size = 1
|
|
||||||
|
|
||||||
lnode := new(LevelNode)
|
|
||||||
lnode.lsize = new(LevelSize)
|
|
||||||
p.level.sub = lnode
|
|
||||||
|
|
||||||
node := new(Node)
|
|
||||||
lnode.sub = node
|
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// String 展示需要的
|
func (pq *PriorityQueue) Push(v interface{}) {
|
||||||
func (pl *PriorityList) String() string {
|
pq.array.Add(v)
|
||||||
|
if pq.isSorted {
|
||||||
content := ""
|
pq.isSorted = false
|
||||||
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertValues 插入值
|
|
||||||
func (pl *PriorityList) InsertValues(values ...interface{}) {
|
|
||||||
|
|
||||||
for _, value := range values {
|
|
||||||
node := new(Node)
|
|
||||||
node.IValue = value
|
|
||||||
|
|
||||||
ll := pl.level
|
|
||||||
// 寻找 适合的level
|
|
||||||
for ll.level != 0 {
|
|
||||||
|
|
||||||
if pl.compare(node, ll.node) > 0 {
|
|
||||||
temp := ll.prev
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 找到数据后
|
|
||||||
if ll.level == 0 {
|
|
||||||
|
|
||||||
if ll.sub == nil {
|
|
||||||
ll.sub = node
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
cur := ll.sub.(*Node)
|
|
||||||
|
|
||||||
isTail := false
|
|
||||||
|
|
||||||
for i := 0; i < ll.lsize.size; i++ {
|
|
||||||
if pl.compare(node, cur) > 0 {
|
|
||||||
|
|
||||||
temp := cur.prev
|
|
||||||
cur.prev = node
|
|
||||||
if temp != nil {
|
|
||||||
node.prev = temp
|
|
||||||
temp.next = node
|
|
||||||
}
|
|
||||||
ll.lsize.size++
|
|
||||||
pl.size++
|
|
||||||
|
|
||||||
isTail = true
|
|
||||||
}
|
|
||||||
cur = cur.next
|
|
||||||
}
|
|
||||||
|
|
||||||
if isTail {
|
|
||||||
temp := cur.next
|
|
||||||
cur.next = node
|
|
||||||
if temp != nil {
|
|
||||||
node.next = temp
|
|
||||||
temp.prev = node
|
|
||||||
}
|
|
||||||
ll.lsize.size++
|
|
||||||
pl.size++
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get 获取索引长度
|
func (pq *PriorityQueue) Values() []interface{} {
|
||||||
// func (pl *PriorityList) Get(idx int) INode {
|
if !pq.isSorted {
|
||||||
|
pq.array.Sort(pq.comparator)
|
||||||
|
pq.isSorted = true
|
||||||
|
|
||||||
// if idx >= pl.size {
|
}
|
||||||
// return nil
|
return pq.array.Values()
|
||||||
// }
|
|
||||||
// cur := pl.head
|
|
||||||
// for i := 0; i < idx; i++ {
|
|
||||||
// cur = cur.GetNext()
|
|
||||||
// }
|
|
||||||
// return cur
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Size 长度
|
|
||||||
func (pl *PriorityList) Size() int {
|
|
||||||
return pl.size
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear 清空链表, 如果外部有引用其中一个节点 要把节点Prev Next值为nil, 三色标记
|
|
||||||
func (pl *PriorityList) Clear() {
|
|
||||||
pl.level = nil
|
|
||||||
pl.size = 0
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,68 @@
|
||||||
package plist
|
package plist
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
func IntCompare(v1, v2 interface{}) int {
|
"github.com/Pallinder/go-randomdata"
|
||||||
if v1.(*Node).ValueInt() > v2.(*Node).ValueInt() {
|
|
||||||
|
"github.com/emirpasic/gods/trees/binaryheap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPriorityQueue(t *testing.T) {
|
||||||
|
p := NewWithInt()
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
p.Push(randomdata.Number(0, 10000))
|
||||||
|
if i%100 == 99 {
|
||||||
|
p.Values()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Error(p.Values())
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPriorityQueue(b *testing.B) {
|
||||||
|
|
||||||
|
p := NewWithInt()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
p.Push(randomdata.Number(0, 10000))
|
||||||
|
if i%1000 == 999 {
|
||||||
|
p.Values()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.Error(p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkList_InsertValues123(b *testing.B) {
|
||||||
|
a := func(v1, v2 interface{}) int {
|
||||||
|
if v1.(int) > v2.(int) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPriorityList_InsertValues(t *testing.T) {
|
h := binaryheap.NewWith(a)
|
||||||
pl := New()
|
|
||||||
pl.compare = IntCompare
|
|
||||||
|
|
||||||
pl.InsertValues(1, 2, 5, 6, 2, 4, 3)
|
TOPK := 50
|
||||||
t.Error(pl.String())
|
|
||||||
|
for i := 0; i < TOPK*1000; i++ {
|
||||||
|
h.Push(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
h.Push(i)
|
||||||
|
l := []interface{}{}
|
||||||
|
for n := 0; n < TOPK; n++ {
|
||||||
|
v, _ := h.Pop()
|
||||||
|
l = append(l, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range l {
|
||||||
|
h.Push(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user