diff --git a/priority_queue/priority_list.go b/priority_queue/priority_list.go index d1e7389..55d31e2 100644 --- a/priority_queue/priority_list.go +++ b/priority_queue/priority_list.go @@ -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 -} - -// PriorityList 跳表 -type PriorityList struct { - 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 - +// NewWithInt compare use int +func NewWithInt() *PriorityQueue { + p := new(PriorityQueue) + p.comparator = func(a, b interface{}) int { + if a.(int) > b.(int) { + return 1 + } + return -1 + } 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 } } -// Get 获取索引长度 -// func (pl *PriorityList) Get(idx int) INode { +func (pq *PriorityQueue) Values() []interface{} { + if !pq.isSorted { + pq.array.Sort(pq.comparator) + pq.isSorted = true -// 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() } diff --git a/priority_queue/priority_list_test.go b/priority_queue/priority_list_test.go index 1f9f483..151d826 100644 --- a/priority_queue/priority_list_test.go +++ b/priority_queue/priority_list_test.go @@ -1,18 +1,68 @@ package plist -import "testing" +import ( + "testing" -func IntCompare(v1, v2 interface{}) int { - if v1.(*Node).ValueInt() > v2.(*Node).ValueInt() { + "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 + } return 1 } - return -1 -} -func TestPriorityList_InsertValues(t *testing.T) { - pl := New() - pl.compare = IntCompare + h := binaryheap.NewWith(a) - pl.InsertValues(1, 2, 5, 6, 2, 4, 3) - t.Error(pl.String()) + 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() }