package plist import ( "log" "github.com/emirpasic/gods/utils" ) // PriorityQueue 优先队列 适合数据量不大, 加索引 type PriorityQueue struct { left, right, mid int datas []interface{} size int comparator utils.Comparator isSorted 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 - 1 x := pq.datas copy(temp[left+1:], pq.datas[pq.left+1:pq.right]) pq.datas = temp pq.left = left pq.mid = mid pq.right = pq.size + pq.left log.Println(x, pq.datas, pq.left, pq.right) } func (pq *PriorityQueue) search(v interface{}) int { // left := pq.left // right := pq.right data := pq.datas[pq.left+1 : pq.right] left := 0 mid := 0 right := len(data) for left < right-1 { mid = (left + right) / 2 // 4 10 7 10 8 10 9 10 | 4 10 4 7 4 5 if pq.comparator(v, data[mid]) > 0 { left = mid } else { right = mid } } if pq.comparator(v, data[left]) > 0 { return left + 1 } else { return left } } func (pq *PriorityQueue) Push(v interface{}) { defer func() { if err := recover(); err != nil { log.Println(pq.datas) log.Println(pq.left, pq.right, pq.size) log.Panic(err) } }() if pq.size == 0 { pq.mid = len(pq.datas) / 2 pq.left = pq.mid - 1 pq.right = pq.mid + 1 pq.datas[pq.mid] = v log.Println(pq.datas) log.Println(pq.left) } 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++ // } else { // if pq.left-1 < 0 { // // 重建 datas // pq.reMakeMemory() // } // pq.left-- // pq.datas[pq.left] = v // } idx := pq.search(v) log.Println("idx:", idx) if idx > pq.size/2 { if pq.right >= len(pq.datas) { pq.reMakeMemory() } offset := pq.left + 1 + idx copy(pq.datas[offset+1:], pq.datas[offset:pq.right]) pq.datas[offset] = v pq.right++ // log.Println("right: ", pq.datas) } else { if pq.left < 0 { // 重建 datas pq.reMakeMemory() } offset := pq.left + 1 + idx copy(pq.datas[pq.left:], pq.datas[pq.left+1:offset]) pq.datas[offset] = v pq.left-- // log.Println("left: ", pq.datas) } } pq.size++ log.Println("push:", pq.datas) // if pq.isSorted { // pq.isSorted = false // } } // 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.isSorted { // utils.Sort(values, pq.comparator) // pq.isSorted = true // } return pq.datas[pq.left:pq.right] }