From 5d99146aec1d5b8152b704a86bd4dd887e5771bf Mon Sep 17 00:00:00 2001 From: huangsimin Date: Wed, 13 Feb 2019 16:47:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E5=8D=95=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E4=BC=98=E5=85=88=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- priority_queue/priority_queue.go | 105 ++++++++++++++------------ priority_queue/priority_queue_test.go | 33 ++++---- 2 files changed, 72 insertions(+), 66 deletions(-) diff --git a/priority_queue/priority_queue.go b/priority_queue/priority_queue.go index fea7759..f99aa14 100644 --- a/priority_queue/priority_queue.go +++ b/priority_queue/priority_queue.go @@ -7,8 +7,11 @@ import ( // PriorityQueue 优先队列 适合数据量不大, 加索引 type PriorityQueue struct { - index *Index + index *Index + indexlimit int + spanlimit int + node *Node size int comparator utils.Comparator @@ -17,12 +20,12 @@ type PriorityQueue struct { type Index struct { node *Node next *Index + nlen int } type Node struct { value interface{} - // prev *Node next *Node } @@ -43,14 +46,6 @@ 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) + "-" } @@ -68,27 +63,10 @@ func (pq *PriorityQueue) String() string { return content + "\n" + idxContent } -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 - } +func (pq *PriorityQueue) findIndexStart(v interface{}) *Index { // find the node of index to start idx := pq.index - for { - if idx.next == nil { break } @@ -99,29 +77,72 @@ func (pq *PriorityQueue) Push(v interface{}) { idx = idx.next } + return idx +} + +func (pq *PriorityQueue) Get(index int) (interface{}, bool) { + if index < 0 || index >= pq.size { + return nil, false + } + + idx := pq.index + movesize := index + for { + if movesize-idx.nlen <= 0 { + break + } else { + movesize -= idx.nlen + idx = idx.next + } + } + cur := idx.node + for movesize > 0 { + movesize-- + cur = cur.next + } + + return cur.value, true +} + +func (pq *PriorityQueue) Push(v interface{}) { + + node := new(Node) + node.value = v + pq.size++ + + 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.findIndexStart(v) 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 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 + idx = idx.next + i = 0 } else { index := new(Index) index.node = cur @@ -133,41 +154,27 @@ func (pq *PriorityQueue) Push(v interface{}) { idx = index i = 0 } - } if pq.comparator(v, cur.next.value) > 0 { temp := cur.next cur.next = node node.next = temp - // node.prev = cur - // temp.prev = node - idx.nlen++ - - // if pq.index.nlen >= pq.indexlimit { - // // 分裂 - - // } - return } - cur = cur.next } cur.next = node - - // node.prev = cur - pq.size++ idx.nlen++ } -// func (pq *PriorityQueue) Top() (interface{}, bool) { -// return pq.Get(0) -// } +func (pq *PriorityQueue) Top() (interface{}, bool) { + return pq.Get(0) +} // func (pq *PriorityQueue) Bottom() (interface{}, bool) { // return pq.Get(pq.right - 1) diff --git a/priority_queue/priority_queue_test.go b/priority_queue/priority_queue_test.go index 2a88264..566e394 100644 --- a/priority_queue/priority_queue_test.go +++ b/priority_queue/priority_queue_test.go @@ -1,7 +1,6 @@ package plist import ( - "log" "testing" "github.com/emirpasic/gods/utils" @@ -11,30 +10,30 @@ 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() +func TestGetPriorityQueue(t *testing.T) { + p := NewWithInt() + var l []int for i := 0; i < 10; i++ { - h1.Push(i) + l = append(l, randomdata.Number(0, 10000)) } - h1.Values()[0] = 3 + for _, v := range l { + p.Push(v) + t.Log(p.String()) + } - log.Println(h1) + t.Error(l) + t.Error(p.String()) + + for _, i := range []int{-1, 0, p.size / 2, p.size - 1, p.size} { + v, ok := p.Get(i) + t.Error(i, v, ok) + } } -func TestPriorityQueue(t *testing.T) { +func TestPustPriorityQueue(t *testing.T) { p := NewWithInt() for i := 0; i < 100; i++ {