diff --git a/priority_queue/priority_list.go b/priority_queue/priority_list.go deleted file mode 100644 index 00a0b1c..0000000 --- a/priority_queue/priority_list.go +++ /dev/null @@ -1,58 +0,0 @@ -package plist - -import ( - "github.com/davecgh/go-spew/spew" -) - -// Node 节点结构 -type Node struct { - next *Node - value interface{} -} - -// PriorityList -type PriorityList struct { - size int - head *Node -} - -// New a node -func New() *PriorityList { - p := new(PriorityList) - return p -} - -// String 展示需要的 -func (pl *PriorityList) String() string { - - content := "" - - for cur := pl.head; cur != nil; cur = cur.next { - content += spew.Sprint(cur.value) + "-" - } - - if content != "" && content[len(content)-1] == '-' { - content = content[:len(content)-1] - } - - return content -} - -// insert 插入值 -func (pl *PriorityList) nodeInsert(cur *Node, value interface{}) { - if cur == nil { - temp := pl.head - pl.head = &Node{value: value} - pl.head.next = temp - return - } - - temp := cur.next - cur.next = &Node{value: value} - cur.next.next = temp -} - -// Size 长度 -func (pl *PriorityList) Size() int { - return pl.size -} diff --git a/priority_queue/priority_queue.go b/priority_queue/priority_queue.go index 5d2897b..1934c8f 100644 --- a/priority_queue/priority_queue.go +++ b/priority_queue/priority_queue.go @@ -1,41 +1,33 @@ package plist import ( + "errors" "log" - "strings" "github.com/davecgh/go-spew/spew" - "github.com/emirpasic/gods/trees/avltree" + + "github.com/emirpasic/gods/trees/binaryheap" + "github.com/emirpasic/gods/utils" ) // PriorityQueue 优先队列 适合数据量不大, 加索引 type PriorityQueue struct { - avl *avltree.Tree + heaps []*binaryheap.Heap + heapsCap int + cursor int + + splitlimit int size int comparator utils.Comparator - splitlimit int } func (pq *PriorityQueue) String() string { content := "" - iter := pq.avl.Iterator() - for !iter.Last() { - iter.Next() - } - - for iter.Prev() { - pl := iter.Value().(*PriorityList) - - cur := pl.head - for cur != nil { - content += spew.Sprint(cur.value) + "-" - cur = cur.next - } - content = strings.TrimRight(content, "-") - content += " ~ " + for i := pq.cursor; i < pq.heapsCap; i++ { + content += spew.Sprint(pq.heaps[i].Values()) + "--" } return content @@ -43,6 +35,11 @@ func (pq *PriorityQueue) String() string { func NewWithIntComparator() *PriorityQueue { pq := new(PriorityQueue) + pq.splitlimit = 20 + pq.heapsCap = 10 + pq.heaps = make([]*binaryheap.Heap, pq.heapsCap, pq.heapsCap) + pq.cursor = pq.heapsCap - 1 + pq.comparator = func(v1, v2 interface{}) int { if v1.(int) > v2.(int) { return 1 @@ -51,78 +48,35 @@ func NewWithIntComparator() *PriorityQueue { } return 0 } - pq.avl = avltree.NewWith(pq.comparator) - pq.splitlimit = 8 - pq.size = 0 + pq.heaps[pq.cursor] = binaryheap.NewWith(pq.comparator) return pq } func (pq *PriorityQueue) Push(value interface{}) { - var pl *PriorityList pq.size++ - defer func() { - if pl.size >= pq.splitlimit { - moveIndex := pl.size / 2 - cur := pl.head - for i := 1; i < moveIndex; i++ { - cur = cur.next + curheap := pq.heaps[pq.cursor] + log.Println(pq.heaps) + if curheap.Size() >= pq.splitlimit { + if pq.cursor == 0 { + // remake + } + pq.cursor-- + heap := binaryheap.NewWith(pq.comparator) + heap.Push(value) + for i := 0; i < pq.splitlimit/2-1; i++ { + v, ok := curheap.Pop() + if !ok { + panic(errors.New("size is error?")) } - log.Println("pq:", pq.String()) - temp := cur.next - cur.next = nil - - plsp := &PriorityList{} - plsp.head = temp - plsp.size = pl.size - moveIndex - - pl.size = moveIndex - - pq.avl.Put(plsp.head.value, plsp) - log.Println("list:", pl.head.value, pl.String()) - log.Println("list:", plsp.head.value, plsp.String()) - log.Println("pq:", pq.avl.Values()) - log.Println("pq:", pq.String(), "\n----------") + heap.Push(v) } - }() - - floor, ok := pq.avl.Floor(value) - if ok { - - pl = floor.Value.(*PriorityList) - cur := pl.head - pl.size++ - - if pq.comparator(value, cur.value) > 0 { - - temp := pl.head - pl.head = &Node{value: value} - pl.head.next = temp - - return - } - - for cur.next != nil { - if pq.comparator(value, cur.next.value) >= 0 { - temp := cur.next - cur.next = &Node{value: value} - cur.next.next = temp - return - } - cur = cur.next - } - // next == nil - cur.next = &Node{value: value} - return + pq.heaps[pq.cursor] = heap + } else { + curheap.Push(value) } - pl = &PriorityList{} - pl.head = &Node{value: value} - pl.size++ - - pq.avl.Put(pl.head.value, pl) - return } diff --git a/priority_queue/priority_queue_test.go b/priority_queue/priority_queue_test.go index f2ab7d4..86e7491 100644 --- a/priority_queue/priority_queue_test.go +++ b/priority_queue/priority_queue_test.go @@ -12,22 +12,6 @@ import ( "github.com/emirpasic/gods/trees/binaryheap" ) -func TestPList(t *testing.T) { - pl := &PriorityList{} - for i := 0; i < 10; i++ { - pl.nodeInsert(nil, randomdata.Number(0, 10)) - } - t.Error(pl.String()) - - cur := pl.head - for i := 0; i < 5; i++ { - cur = cur.next - } - pl.nodeInsert(cur, 11) - - t.Error(pl.String()) -} - func TestPQ(t *testing.T) { var l []int @@ -48,40 +32,10 @@ func TestPQ(t *testing.T) { } func BenchmarkPQ(b *testing.B) { - pq := NewWithIntComparator() - - b.N = 1000000 - for i := b.N; i > 0; i-- { - pq.Push(i) - } - - iter := pq.avl.Iterator() - iter.Next() - - pl := iter.Value().(*PriorityList) - b.Log(pq.size, pq.avl.Size(), pl.Size(), pl.head) - b.Log(pl.head.value) - if pl.head.next != nil { - b.Log(pl.head.next.value) - } // b.Log("all:", pq.avl.Size(), pq.avl.Values()) } -func BenchmarkPList(b *testing.B) { - - for i := 0; i < b.N; i++ { - pl := &PriorityList{} - for i2 := 0; i2 < 5; i2++ { - cur := pl.head - for n := 0; n < i2; n++ { - cur = cur.next - } - pl.nodeInsert(cur, i2) - } - } -} - func TestAvl(t *testing.T) { comparator := func(v1, v2 interface{}) int {