TODO: 设计出几种不同优先队列的架构.

This commit is contained in:
huangsimin 2019-01-30 18:37:12 +08:00
parent ad18004bc2
commit 055113962d
2 changed files with 86 additions and 142 deletions

View File

@ -1,147 +1,41 @@
package plist
import (
"474420502.top/eson/structure"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/utils"
)
type NodeList struct {
head, tail *Node
// PriorityQueue 优先队列
type PriorityQueue struct {
array arraylist.List
comparator utils.Comparator
isSorted bool
}
// Node 节点结构
type Node struct {
prev, next *Node
structure.NValue
// NewWithInt compare use int
func NewWithInt() *PriorityQueue {
p := new(PriorityQueue)
p.comparator = func(a, b interface{}) int {
if a.(int) > b.(int) {
return 1
}
// PriorityList 跳表
type PriorityList struct {
size int
compare func(v1, v2 interface{}) int
level *LevelNode
return -1
}
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
}
// String 展示需要的
func (pl *PriorityList) String() string {
content := ""
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++
}
func (pq *PriorityQueue) Push(v interface{}) {
pq.array.Add(v)
if pq.isSorted {
pq.isSorted = false
}
}
func (pq *PriorityQueue) Values() []interface{} {
if !pq.isSorted {
pq.array.Sort(pq.comparator)
pq.isSorted = true
}
// Get 获取索引长度
// func (pl *PriorityList) Get(idx int) INode {
// if idx >= pl.size {
// return nil
// }
// 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
return pq.array.Values()
}

View File

@ -1,18 +1,68 @@
package plist
import "testing"
import (
"testing"
func IntCompare(v1, v2 interface{}) int {
if v1.(*Node).ValueInt() > v2.(*Node).ValueInt() {
return 1
"github.com/Pallinder/go-randomdata"
"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
}
func TestPriorityList_InsertValues(t *testing.T) {
pl := New()
pl.compare = IntCompare
pl.InsertValues(1, 2, 5, 6, 2, 4, 3)
t.Error(pl.String())
return 1
}
h := binaryheap.NewWith(a)
TOPK := 50
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()
}