diff --git a/priority_queue/priority_queue.go b/priority_queue/priority_queue.go index c9f2600..74d8f38 100644 --- a/priority_queue/priority_queue.go +++ b/priority_queue/priority_queue.go @@ -7,30 +7,21 @@ import ( // PriorityQueue 优先队列 适合数据量不大, 加索引 type PriorityQueue struct { - index *Index - indexlimit int - node *Node - size int - comparator utils.Comparator -} - -type Index struct { - node *Node - next *Index - nlen int -} - -type Node struct { - value interface{} - - // prev *Node - next *Node + data []interface{} + left, right, mid int + cap int + size int + isSorted bool + comparator utils.Comparator } // NewWithInt compare use int func NewWithInt() *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 { if a.(int) > b.(int) { return 1 @@ -41,74 +32,61 @@ 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) + "-" - } - - 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 + return "(" + spew.Sprint(pq.data[pq.mid]) + "," + spew.Sprint(pq.size) + ")" + spew.Sprint(pq.Values()) } +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{}) { - node := new(Node) - node.value = v - pq.size++ - - if pq.node == nil { - //创建索引 - pq.node = node + if pq.size == 0 { + pq.data[pq.mid] = v + pq.left = pq.mid + pq.right = pq.mid + 1 + pq.size = 1 return } - cur := pq.node - - //cur := pq.node - if pq.comparator(v, pq.node.value) > 0 { - 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 + midvalue := pq.data[pq.mid] + if pq.comparator(v, midvalue) > 0 { + if pq.left == 0 { + pq.reMakeData() } - 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 - - // node.prev = cur - + pq.isSorted = false + pq.size++ } // func (pq *PriorityQueue) Top() (interface{}, bool) { @@ -126,11 +104,11 @@ func (pq *PriorityQueue) Push(v interface{}) { // return nil, false // } -// func (pq *PriorityQueue) Values() []interface{} { -// // values := pq.datas[pq.left:pq.right] -// // if !pq.isSorted { -// // utils.Sort(values, pq.comparator) -// // pq.isSorted = true -// // } -// return pq.datas[pq.left:pq.right] -// } +func (pq *PriorityQueue) Values() []interface{} { + values := pq.data[pq.left:pq.right] + if !pq.isSorted { + utils.Sort(values, pq.comparator) + pq.isSorted = true + } + return values +} diff --git a/priority_queue/priority_queue_test.go b/priority_queue/priority_queue_test.go index 2a88264..785b2fc 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,29 +10,6 @@ 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() - - for i := 0; i < 10; i++ { - h1.Push(i) - } - - h1.Values()[0] = 3 - - log.Println(h1) - -} - func TestPriorityQueue(t *testing.T) { p := NewWithInt() @@ -56,6 +32,9 @@ func BenchmarkPriorityQueue(b *testing.B) { b.N = 100000 for i := 0; i < b.N; i++ { p.Push(randomdata.Number(0, 100000)) + if i%100 == 0 { + p.Values() + } } }