完善priority_queue中, TODO: 继续
This commit is contained in:
parent
055113962d
commit
b2d62bb55a
|
@ -1,41 +0,0 @@
|
|||
package plist
|
||||
|
||||
import (
|
||||
"github.com/emirpasic/gods/lists/arraylist"
|
||||
"github.com/emirpasic/gods/utils"
|
||||
)
|
||||
|
||||
// PriorityQueue 优先队列
|
||||
type PriorityQueue struct {
|
||||
array arraylist.List
|
||||
comparator utils.Comparator
|
||||
isSorted bool
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
return pq.array.Values()
|
||||
}
|
138
priority_queue/priority_queue.go
Normal file
138
priority_queue/priority_queue.go
Normal file
|
@ -0,0 +1,138 @@
|
|||
package plist
|
||||
|
||||
import (
|
||||
"github.com/emirpasic/gods/utils"
|
||||
)
|
||||
|
||||
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
||||
type PriorityQueue struct {
|
||||
left, right, mid int
|
||||
datas []interface{}
|
||||
size int
|
||||
comparator utils.Comparator
|
||||
isLeftSorted bool
|
||||
isRightSorted bool
|
||||
}
|
||||
|
||||
// NewWithInt compare use int
|
||||
func NewWithInt() *PriorityQueue {
|
||||
p := new(PriorityQueue)
|
||||
p.datas = make([]interface{}, 8)
|
||||
p.comparator = func(a, b interface{}) int {
|
||||
if a.(int) > b.(int) {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) reArrange() {
|
||||
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) reMakeMemory() {
|
||||
|
||||
var incSize int
|
||||
if pq.size >= 1048 {
|
||||
incSize = pq.size / 2
|
||||
} else {
|
||||
incSize = pq.size
|
||||
}
|
||||
|
||||
capacity := pq.size + incSize
|
||||
temp := make([]interface{}, capacity)
|
||||
|
||||
mid := capacity / 2
|
||||
left := mid - pq.size/2
|
||||
|
||||
copy(temp[left:], pq.datas[pq.left:pq.right])
|
||||
pq.datas = temp
|
||||
pq.left = left
|
||||
pq.mid = mid
|
||||
pq.right = pq.size + pq.left
|
||||
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Push(v interface{}) {
|
||||
|
||||
if pq.size == 0 {
|
||||
pq.mid = len(pq.datas) / 2
|
||||
pq.left = pq.mid
|
||||
pq.right = pq.mid + 1
|
||||
|
||||
pq.datas[pq.mid] = v
|
||||
|
||||
} else {
|
||||
|
||||
if pq.comparator(v, pq.datas[pq.mid]) > 0 {
|
||||
|
||||
if pq.right >= len(pq.datas) {
|
||||
// 重建 datas
|
||||
pq.reMakeMemory()
|
||||
}
|
||||
|
||||
pq.datas[pq.right] = v
|
||||
pq.right++
|
||||
|
||||
if pq.isRightSorted {
|
||||
pq.isRightSorted = false
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if pq.left-1 < 0 {
|
||||
// 重建 datas
|
||||
pq.reMakeMemory()
|
||||
}
|
||||
pq.left--
|
||||
pq.datas[pq.left] = v
|
||||
|
||||
if pq.isLeftSorted {
|
||||
pq.isLeftSorted = false
|
||||
}
|
||||
}
|
||||
}
|
||||
pq.size++
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) PopTop() (interface{}, bool) {
|
||||
|
||||
return v, isok
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) PopBottom() (interface{}, bool) {
|
||||
|
||||
return v, isok
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Top() (interface{}, bool) {
|
||||
return pq.Get(0)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Bottom() (interface{}, bool) {
|
||||
return pq.Get(pq.right - 1)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
|
||||
if index < pq.size {
|
||||
return pq.Values()[index], true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Values() []interface{} {
|
||||
values := pq.datas[pq.left:pq.right]
|
||||
|
||||
if !pq.isLeftSorted {
|
||||
utils.Sort(values[0:pq.size/2], pq.comparator)
|
||||
pq.isLeftSorted = true
|
||||
}
|
||||
|
||||
if !pq.isRightSorted {
|
||||
utils.Sort(values[pq.size/2:], pq.comparator)
|
||||
pq.isRightSorted = true
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
|
@ -3,6 +3,8 @@ package plist
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/emirpasic/gods/utils"
|
||||
|
||||
"github.com/Pallinder/go-randomdata"
|
||||
|
||||
"github.com/emirpasic/gods/trees/binaryheap"
|
||||
|
@ -11,23 +13,25 @@ import (
|
|||
func TestPriorityQueue(t *testing.T) {
|
||||
p := NewWithInt()
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
for i := 0; i < 20; i++ {
|
||||
p.Push(randomdata.Number(0, 10000))
|
||||
if i%100 == 99 {
|
||||
p.Values()
|
||||
}
|
||||
}
|
||||
|
||||
t.Error(p.Values())
|
||||
t.Error(p.datas, p.size, len(p.Values()))
|
||||
|
||||
for _, idx := range []int{5, 0, 21, 19} {
|
||||
t.Error(p.Get(idx))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkPriorityQueue(b *testing.B) {
|
||||
|
||||
func BenchmarkPriorityQueue10(b *testing.B) {
|
||||
p := NewWithInt()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.Push(randomdata.Number(0, 10000))
|
||||
if i%1000 == 999 {
|
||||
p.Push(randomdata.Number(0, 100000))
|
||||
if i%10 == 0 {
|
||||
p.Values()
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +39,20 @@ func BenchmarkPriorityQueue(b *testing.B) {
|
|||
// t.Error(p.String())
|
||||
}
|
||||
|
||||
func TestHeap(t *testing.T) {
|
||||
heap := binaryheap.NewWithIntComparator()
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
heap.Push(randomdata.Number(0, 1000))
|
||||
}
|
||||
|
||||
t.Error(heap.Peek())
|
||||
t.Error(heap.Values())
|
||||
|
||||
utils.Sort(heap.Values(), utils.IntComparator)
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkList_InsertValues123(b *testing.B) {
|
||||
a := func(v1, v2 interface{}) int {
|
||||
if v1.(int) > v2.(int) {
|
Loading…
Reference in New Issue
Block a user