2019-05-10 10:01:15 +00:00
|
|
|
package plist
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/474420502/focus/compare"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Node struct {
|
|
|
|
prev, next *Node
|
|
|
|
value interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
type PriorityList struct {
|
|
|
|
head, tail *Node
|
2019-07-25 03:40:50 +00:00
|
|
|
size uint
|
2019-05-10 10:01:15 +00:00
|
|
|
Compare compare.Compare
|
|
|
|
}
|
|
|
|
|
2019-07-25 03:40:50 +00:00
|
|
|
// 优先队列的Index 正负都有作用要定义一种新的接口类型
|
|
|
|
func assertImplementation() {
|
|
|
|
// var _ list.IList = (*PriorityList)(nil)
|
|
|
|
}
|
|
|
|
|
2019-05-10 10:01:15 +00:00
|
|
|
func New(Compare compare.Compare) *PriorityList {
|
|
|
|
pl := &PriorityList{head: &Node{}, tail: &Node{}, size: 0, Compare: Compare}
|
|
|
|
pl.head.next = pl.tail
|
|
|
|
pl.tail.prev = pl.head
|
|
|
|
return pl
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) String() string {
|
|
|
|
content := ""
|
|
|
|
|
|
|
|
cur := pl.head.next
|
|
|
|
|
|
|
|
for ; cur != pl.tail; cur = cur.next {
|
|
|
|
content += spew.Sprint(cur.value) + " "
|
|
|
|
}
|
|
|
|
content = strings.TrimRight(content, " ")
|
|
|
|
return content
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) RString() string {
|
|
|
|
content := ""
|
|
|
|
|
|
|
|
cur := pl.tail.prev
|
|
|
|
|
|
|
|
for ; cur != pl.head; cur = cur.prev {
|
|
|
|
content += spew.Sprint(cur.value) + " "
|
|
|
|
}
|
|
|
|
content = strings.TrimRight(content, " ")
|
|
|
|
return content
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) Iterator() *Iterator {
|
|
|
|
return &Iterator{pl: pl, cur: pl.head}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) CircularIterator() *CircularIterator {
|
|
|
|
return &CircularIterator{pl: pl, cur: pl.head}
|
|
|
|
}
|
|
|
|
|
2019-07-25 03:40:50 +00:00
|
|
|
func (pl *PriorityList) Size() uint {
|
2019-05-10 10:01:15 +00:00
|
|
|
return pl.size
|
|
|
|
}
|
|
|
|
|
2019-07-25 03:40:50 +00:00
|
|
|
func (pl *PriorityList) Empty() bool {
|
|
|
|
return pl.size == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) Clear() {
|
|
|
|
pl.head.next = pl.tail
|
|
|
|
pl.tail.prev = pl.head
|
|
|
|
pl.size = 0
|
|
|
|
}
|
|
|
|
|
2019-05-10 10:01:15 +00:00
|
|
|
func (pl *PriorityList) Push(value interface{}) {
|
|
|
|
pl.size++
|
|
|
|
pnode := &Node{value: value}
|
|
|
|
if pl.size == 1 {
|
|
|
|
pl.head.next = pnode
|
|
|
|
pl.tail.prev = pnode
|
|
|
|
pnode.prev = pl.head
|
|
|
|
pnode.next = pl.tail
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
cur := pl.head
|
|
|
|
for ; cur.next != pl.tail; cur = cur.next {
|
|
|
|
if pl.Compare(value, cur.next.value) > 0 {
|
|
|
|
cnext := cur.next
|
|
|
|
|
|
|
|
cur.next = pnode
|
|
|
|
cnext.prev = pnode
|
|
|
|
pnode.prev = cur
|
|
|
|
pnode.next = cnext
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cur.next = pnode
|
|
|
|
pnode.prev = cur
|
|
|
|
pnode.next = pl.tail
|
|
|
|
pl.tail.prev = pnode
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) Top() (result interface{}, ok bool) {
|
|
|
|
if pl.size > 0 {
|
|
|
|
return pl.head.next.value, true
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) Pop() (result interface{}, ok bool) {
|
|
|
|
if pl.size > 0 {
|
|
|
|
pl.size--
|
|
|
|
temp := pl.head.next
|
|
|
|
temp.next.prev = pl.head
|
|
|
|
pl.head.next = temp.next
|
|
|
|
return temp.value, true
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2019-07-25 03:40:50 +00:00
|
|
|
func (pl *PriorityList) Index(idx int) (interface{}, bool) {
|
2019-05-10 10:01:15 +00:00
|
|
|
if n, ok := pl.GetNode(idx); ok {
|
|
|
|
return n.value, true
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2019-07-25 03:40:50 +00:00
|
|
|
func (l *PriorityList) Contains(values ...interface{}) bool {
|
|
|
|
|
|
|
|
for _, searchValue := range values {
|
|
|
|
found := false
|
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
|
|
|
if cur.value == searchValue {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-05-10 10:01:15 +00:00
|
|
|
func (pl *PriorityList) GetNode(idx int) (*Node, bool) {
|
|
|
|
if idx >= 0 {
|
|
|
|
cur := pl.head.next
|
|
|
|
for i := 0; cur != pl.tail; i++ {
|
|
|
|
if i == idx {
|
|
|
|
return cur, true
|
|
|
|
}
|
|
|
|
cur = cur.next
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cur := pl.tail.prev
|
|
|
|
for i := -1; cur != pl.head; i-- {
|
|
|
|
if i == idx {
|
|
|
|
return cur, true
|
|
|
|
}
|
|
|
|
cur = cur.prev
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) RemoveWithIndex(idx int) {
|
|
|
|
if n, ok := pl.GetNode(idx); ok {
|
|
|
|
pl.Remove(n)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pl *PriorityList) Remove(node *Node) {
|
|
|
|
|
|
|
|
prev := node.prev
|
|
|
|
next := node.next
|
|
|
|
prev.next = next
|
|
|
|
next.prev = prev
|
|
|
|
|
|
|
|
node.prev = nil
|
|
|
|
node.next = nil
|
|
|
|
|
|
|
|
pl.size--
|
|
|
|
}
|
|
|
|
func (pl *PriorityList) Values() []interface{} {
|
|
|
|
values := make([]interface{}, pl.size, pl.size)
|
|
|
|
for i, cur := 0, pl.head.next; cur != pl.tail; i, cur = i+1, cur.next {
|
|
|
|
values[i] = cur.value
|
|
|
|
}
|
|
|
|
return values
|
|
|
|
}
|
2019-07-25 03:40:50 +00:00
|
|
|
|
|
|
|
func (l *PriorityList) Traversal(every func(interface{}) bool) {
|
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
|
|
|
if !every(cur.value) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|