Compare commits
12 Commits
master
...
queue_inde
Author | SHA1 | Date | |
---|---|---|---|
5c3828542b | |||
0fb5a2ca4a | |||
26ba5a9e0a | |||
8c05215122 | |||
|
6aff3d9af4 | ||
|
6e249d4634 | ||
|
86a8ee1198 | ||
62c2c2cb8f | |||
|
cc50678b6a | ||
|
b5498a257b | ||
|
cd40d47a3c | ||
|
5d99146aec |
|
@ -1,249 +0,0 @@
|
||||||
package clinked
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CNode 循环链表 三色标记 不确定是否会清除循环引用, 网上说会
|
|
||||||
type CNode struct {
|
|
||||||
value interface{}
|
|
||||||
prev *CNode
|
|
||||||
next *CNode
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue 获取到Node的值
|
|
||||||
func (node *CNode) GetValue() interface{} {
|
|
||||||
return node.value
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValue 获取到Node的值
|
|
||||||
func (node *CNode) SetValue(value interface{}) {
|
|
||||||
node.value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// CircularLinked 循环链表
|
|
||||||
type CircularLinked struct {
|
|
||||||
cursor *CNode
|
|
||||||
head *CNode
|
|
||||||
tail *CNode
|
|
||||||
size uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCircularLinked create a CircularLinked
|
|
||||||
func NewCircularLinked(values ...interface{}) *CircularLinked {
|
|
||||||
list := &CircularLinked{}
|
|
||||||
if len(values) > 0 {
|
|
||||||
list.Append(values...)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
// Head 链表的首
|
|
||||||
func (list *CircularLinked) Head() *CNode {
|
|
||||||
return list.head
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tail 链表的首
|
|
||||||
func (list *CircularLinked) Tail() *CNode {
|
|
||||||
return list.tail
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cursor get current Cursor
|
|
||||||
func (list *CircularLinked) Cursor() *CNode {
|
|
||||||
if list.cursor == nil {
|
|
||||||
list.cursor = list.head
|
|
||||||
}
|
|
||||||
return list.cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveNext get next Cursor
|
|
||||||
func (list *CircularLinked) MoveNext() *CNode {
|
|
||||||
if list.cursor == nil {
|
|
||||||
list.cursor = list.head
|
|
||||||
}
|
|
||||||
list.cursor = list.cursor.next
|
|
||||||
return list.cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
// MovePrev get prev Cursor
|
|
||||||
func (list *CircularLinked) MovePrev() *CNode {
|
|
||||||
if list.cursor == nil {
|
|
||||||
list.cursor = list.head
|
|
||||||
}
|
|
||||||
list.cursor = list.cursor.prev
|
|
||||||
return list.cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
// CursorToHead cursor move to head
|
|
||||||
func (list *CircularLinked) CursorToHead() *CNode {
|
|
||||||
list.cursor = list.head
|
|
||||||
return list.cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
// CursorToTail cursor move to tail
|
|
||||||
func (list *CircularLinked) CursorToTail() *CNode {
|
|
||||||
list.cursor = list.tail
|
|
||||||
return list.cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLoopValues 获取从头到尾的值
|
|
||||||
func (list *CircularLinked) GetLoopValues() []*CNode {
|
|
||||||
var result []*CNode
|
|
||||||
|
|
||||||
if list.head != nil {
|
|
||||||
result = append(result, list.head)
|
|
||||||
for cur := list.head.next; cur != list.head; cur = cur.next {
|
|
||||||
result = append(result, cur)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append a value (one or more) at the end of the list (same as Append())
|
|
||||||
func (list *CircularLinked) Append(values ...interface{}) {
|
|
||||||
for _, value := range values {
|
|
||||||
node := &CNode{value: value}
|
|
||||||
if list.size == 0 {
|
|
||||||
list.head = node
|
|
||||||
list.tail = node
|
|
||||||
node.next = node
|
|
||||||
node.prev = node
|
|
||||||
} else {
|
|
||||||
list.tail.next = node
|
|
||||||
node.next = list.head
|
|
||||||
node.prev = list.tail
|
|
||||||
list.tail = node
|
|
||||||
}
|
|
||||||
list.size++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove 移除一些节点
|
|
||||||
func (list *CircularLinked) Remove(node *CNode) {
|
|
||||||
|
|
||||||
switch list.size {
|
|
||||||
case 0:
|
|
||||||
list.errorNotInList(node)
|
|
||||||
case 1:
|
|
||||||
if list.head == node {
|
|
||||||
list.head = nil
|
|
||||||
list.tail = nil
|
|
||||||
node.next = nil
|
|
||||||
node.prev = nil
|
|
||||||
list.cursor = nil
|
|
||||||
list.size--
|
|
||||||
} else {
|
|
||||||
list.errorNotInList(node)
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
|
|
||||||
node.prev = nil
|
|
||||||
node.next = nil
|
|
||||||
|
|
||||||
switch node {
|
|
||||||
case list.head:
|
|
||||||
list.head = list.tail
|
|
||||||
list.tail.prev = list.head
|
|
||||||
list.head.next = list.tail
|
|
||||||
list.cursor = list.head
|
|
||||||
list.size--
|
|
||||||
case list.tail:
|
|
||||||
list.tail = list.head
|
|
||||||
list.tail.prev = list.head
|
|
||||||
list.head.next = list.tail
|
|
||||||
list.cursor = list.head
|
|
||||||
list.size--
|
|
||||||
default:
|
|
||||||
list.errorNotInList(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
switch node {
|
|
||||||
case list.head:
|
|
||||||
_, next := list.cutAndSplice(node)
|
|
||||||
list.size--
|
|
||||||
list.head = next
|
|
||||||
if list.cursor == node {
|
|
||||||
list.cursor = next
|
|
||||||
}
|
|
||||||
case list.tail:
|
|
||||||
prev, _ := list.cutAndSplice(node)
|
|
||||||
list.size--
|
|
||||||
list.tail = prev
|
|
||||||
if list.cursor == node {
|
|
||||||
list.cursor = prev
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
_, next := list.cutAndSplice(node)
|
|
||||||
list.size--
|
|
||||||
if list.cursor == node {
|
|
||||||
list.cursor = next
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookCursor for list show
|
|
||||||
func (list *CircularLinked) LookCursor() string {
|
|
||||||
cursor := list.Cursor()
|
|
||||||
|
|
||||||
content := "->["
|
|
||||||
cur := list.head
|
|
||||||
if list.size != 0 {
|
|
||||||
for size := uint64(0); size < list.size; size++ {
|
|
||||||
if cursor == cur {
|
|
||||||
content += "(" + spew.Sprint(cur.value) + ")" + ", "
|
|
||||||
} else {
|
|
||||||
content += spew.Sprint(cur.value) + ", "
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = cur.next
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content = strings.TrimRight(content, ", ")
|
|
||||||
showlen := len(content)
|
|
||||||
if showlen >= 64 {
|
|
||||||
showlen = 64
|
|
||||||
}
|
|
||||||
content += "]" + content[0:showlen] + " ..."
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear for list show
|
|
||||||
func (list *CircularLinked) Clear() {
|
|
||||||
if list.size != 0 {
|
|
||||||
list.head.prev = nil
|
|
||||||
list.tail.next = nil
|
|
||||||
list.head = nil
|
|
||||||
list.tail = nil
|
|
||||||
list.cursor = nil
|
|
||||||
list.size = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size for list show
|
|
||||||
func (list *CircularLinked) Size() uint64 {
|
|
||||||
return list.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (list *CircularLinked) errorNotInList(node *CNode) {
|
|
||||||
log.Println("the node value ", spew.Sprint(node), " is not in list")
|
|
||||||
}
|
|
||||||
|
|
||||||
// cutAndSplice (不考虑边界情况)
|
|
||||||
func (list *CircularLinked) cutAndSplice(node *CNode) (prev, next *CNode) {
|
|
||||||
prev = node.prev
|
|
||||||
next = node.next
|
|
||||||
|
|
||||||
prev.next = next
|
|
||||||
next.prev = prev
|
|
||||||
|
|
||||||
node.prev = nil
|
|
||||||
node.next = nil
|
|
||||||
|
|
||||||
return prev, next
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package clinked
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestCircularLinkedLookUp(t *testing.T) {
|
|
||||||
|
|
||||||
cl := NewCircularLinked(1, 2, 3, 4, 5, 6)
|
|
||||||
if !(cl.head.value.(int) == 1 && cl.tail.value.(int) == 6) {
|
|
||||||
t.Error(cl.LookCursor())
|
|
||||||
}
|
|
||||||
|
|
||||||
cl = NewCircularLinked(6, 2, 3, 4, 5, 1)
|
|
||||||
if !(cl.head.value.(int) == 6 && cl.tail.value.(int) == 1) {
|
|
||||||
t.Error("New List is error:", cl.LookCursor())
|
|
||||||
}
|
|
||||||
|
|
||||||
if cl.MoveNext().value.(int) != 2 {
|
|
||||||
t.Error("CursorNext error:", cl.LookCursor())
|
|
||||||
}
|
|
||||||
|
|
||||||
cl = NewCircularLinked(0, 1, 2, 3, 4, 5)
|
|
||||||
for i := 0; i < 6; i++ {
|
|
||||||
if cl.Cursor().value.(int) != i {
|
|
||||||
t.Error("CursorNext error:", cl.LookCursor())
|
|
||||||
}
|
|
||||||
cl.MoveNext()
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < 6; i++ {
|
|
||||||
if cl.Cursor().value.(int) != i {
|
|
||||||
t.Error("CursorNext loop error:", cl.LookCursor())
|
|
||||||
}
|
|
||||||
cl.MoveNext()
|
|
||||||
}
|
|
||||||
|
|
||||||
cl = NewCircularLinked(6, 2, 3, 4, 5, 1)
|
|
||||||
cl.Remove(cl.Cursor())
|
|
||||||
if cl.Cursor().value != 2 {
|
|
||||||
t.Error("Remove Head is error", cl.LookCursor())
|
|
||||||
}
|
|
||||||
cl.Remove(cl.CursorToTail())
|
|
||||||
if cl.Cursor().value != 5 {
|
|
||||||
t.Error("Remove CursorToTail is error", cl.LookCursor())
|
|
||||||
}
|
|
||||||
|
|
||||||
cl.Remove(cl.CursorToHead())
|
|
||||||
if cl.Cursor().value != 3 {
|
|
||||||
t.Error("Remove CursorToHead is error", cl.LookCursor())
|
|
||||||
}
|
|
||||||
|
|
||||||
limitCount := 0
|
|
||||||
for cl.Size() > 0 {
|
|
||||||
cl.Remove(cl.Cursor())
|
|
||||||
limitCount++
|
|
||||||
if limitCount >= 10 {
|
|
||||||
t.Error("Not Clear", cl.LookCursor())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cl.Remove(cl.CursorToHead()) // nil is not in list is success!
|
|
||||||
if cl.head != nil || cl.tail != nil || cl.cursor != nil {
|
|
||||||
t.Error("Remove Boundary error")
|
|
||||||
}
|
|
||||||
}
|
|
70
priority_list/iterator.go
Normal file
70
priority_list/iterator.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package plist
|
||||||
|
|
||||||
|
type Iterator struct {
|
||||||
|
pl *PriorityList
|
||||||
|
cur *Node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) Value() interface{} {
|
||||||
|
return iter.cur.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) RingNext() bool {
|
||||||
|
if iter.pl.size == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
iter.cur = iter.cur.next
|
||||||
|
if iter.cur == iter.pl.tail {
|
||||||
|
iter.cur = iter.pl.head.next
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) Next() bool {
|
||||||
|
if iter.cur == iter.pl.tail {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if iter.cur.next == iter.pl.tail {
|
||||||
|
iter.cur = iter.cur.next
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
iter.cur = iter.cur.next
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) RingPrev() bool {
|
||||||
|
if iter.pl.size == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
iter.cur = iter.cur.prev
|
||||||
|
if iter.cur == iter.pl.head {
|
||||||
|
iter.cur = iter.pl.tail.prev
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) Prev() bool {
|
||||||
|
|
||||||
|
if iter.cur == iter.pl.head {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if iter.cur.prev == iter.pl.head {
|
||||||
|
iter.cur = iter.cur.prev
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
iter.cur = iter.cur.prev
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) MoveHead() {
|
||||||
|
iter.cur = iter.pl.head
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) MoveTail() {
|
||||||
|
iter.cur = iter.pl.tail
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package plist
|
|
||||||
|
|
||||||
// NodeInt plist 现成的Int节点, 可以作为例子
|
|
||||||
type NodeInt struct {
|
|
||||||
Node
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare plist 现成的Int节点Compare覆盖
|
|
||||||
func (fl *NodeInt) Compare(v INode) bool {
|
|
||||||
return fl.GetValue().(int) > v.GetValue().(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNodeInt plist 现成的Int节点, New一个NodeInt
|
|
||||||
func NewNodeInt(v int) (fl *NodeInt) {
|
|
||||||
fl = new(NodeInt)
|
|
||||||
fl.SetValue(v)
|
|
||||||
return fl
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/emirpasic/gods/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// INode 比较的必须继承的接口
|
// INode 比较的必须继承的接口
|
||||||
|
@ -21,59 +22,18 @@ type INode interface {
|
||||||
|
|
||||||
// Node 优先链表的节点
|
// Node 优先链表的节点
|
||||||
type Node struct {
|
type Node struct {
|
||||||
INode
|
next, prev *Node
|
||||||
prev, next INode
|
|
||||||
// isrelease bool
|
// isrelease bool
|
||||||
value interface{}
|
Value interface{}
|
||||||
}
|
|
||||||
|
|
||||||
// NewNode 创建一个PriorityList 节点
|
|
||||||
func NewNode(v interface{}) *Node {
|
|
||||||
n := new(Node)
|
|
||||||
n.SetValue(v)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue 获取值
|
|
||||||
func (node *Node) GetValue() interface{} {
|
|
||||||
return node.value
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValue 设置值
|
|
||||||
func (node *Node) SetValue(v interface{}) {
|
|
||||||
node.value = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPrev 获取left值
|
|
||||||
func (node *Node) GetPrev() INode {
|
|
||||||
return node.prev
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPrev 设置left值
|
|
||||||
func (node *Node) SetPrev(n INode) {
|
|
||||||
node.prev = n
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNext 设置right值
|
|
||||||
func (node *Node) GetNext() INode {
|
|
||||||
return node.next
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNext 获取left值
|
|
||||||
func (node *Node) SetNext(n INode) {
|
|
||||||
node.next = n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (node *Node) String() string {
|
|
||||||
return spew.Sprint(node.value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PriorityList 优先列表
|
// PriorityList 优先列表
|
||||||
type PriorityList struct {
|
type PriorityList struct {
|
||||||
head INode
|
head *Node
|
||||||
tail INode
|
tail *Node
|
||||||
|
|
||||||
size int
|
compartor utils.Comparator
|
||||||
|
size int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size 长度
|
// Size 长度
|
||||||
|
@ -84,135 +44,73 @@ func (pl *PriorityList) Size() int {
|
||||||
// Clear 清空链表, 如果外部有引用其中一个节点 要把节点Prev Next值为nil, 三色标记
|
// Clear 清空链表, 如果外部有引用其中一个节点 要把节点Prev Next值为nil, 三色标记
|
||||||
func (pl *PriorityList) Clear() {
|
func (pl *PriorityList) Clear() {
|
||||||
pl.head = nil
|
pl.head = nil
|
||||||
pl.tail = nil
|
|
||||||
pl.size = 0
|
pl.size = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCompare 获取比较的节点 compare >= 11这个节点小的值 [15,12,9,8,6,1] = 9
|
// // ForEach 顺序遍历
|
||||||
func (pl *PriorityList) GetCompare(cNode INode) INode {
|
// func (pl *PriorityList) ForEach(eachfunc func(*Node) *Node) {
|
||||||
cur := pl.head
|
// cur := pl.head
|
||||||
for cur != nil {
|
// }
|
||||||
if !cur.Compare(cNode) {
|
|
||||||
return cur
|
|
||||||
}
|
|
||||||
cur = cur.GetNext()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCompareReverse 逆序获取比较的节点 compare >= 11这个节点大的值 [15,12,9,8,6,1] = 12
|
|
||||||
func (pl *PriorityList) GetCompareReverse(cNode INode) INode {
|
|
||||||
cur := pl.tail
|
|
||||||
for cur != nil {
|
|
||||||
if cur.Compare(cNode) {
|
|
||||||
return cur
|
|
||||||
}
|
|
||||||
cur = cur.GetPrev()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForEach 顺序遍历
|
|
||||||
func (pl *PriorityList) ForEach(eachfunc func(INode) bool) {
|
|
||||||
cur := pl.head
|
|
||||||
for cur != nil {
|
|
||||||
if !eachfunc(cur) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cur = cur.GetNext()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForEachReverse 逆遍历
|
|
||||||
func (pl *PriorityList) ForEachReverse(eachfunc func(INode) bool) {
|
|
||||||
cur := pl.tail
|
|
||||||
for cur != nil {
|
|
||||||
if !eachfunc(cur) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cur = cur.GetPrev()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get 获取索引长度
|
// Get 获取索引长度
|
||||||
func (pl *PriorityList) Get(idx int) INode {
|
func (pl *PriorityList) Get(idx int) interface{} {
|
||||||
if idx >= pl.size {
|
node := pl.GetNode(idx)
|
||||||
return nil
|
if node != nil {
|
||||||
|
return node.Value
|
||||||
}
|
}
|
||||||
cur := pl.head
|
return nil
|
||||||
for i := 0; i < idx; i++ {
|
|
||||||
cur = cur.GetNext()
|
|
||||||
}
|
|
||||||
return cur
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReverse 腻序获取索引长度
|
// GetNode 获取索引长度
|
||||||
func (pl *PriorityList) GetReverse(idx int) INode {
|
func (pl *PriorityList) GetNode(idx int) *Node {
|
||||||
if idx >= pl.size {
|
if idx >= 0 {
|
||||||
return nil
|
cur := pl.head.next
|
||||||
}
|
for i := 0; cur != pl.tail; i++ {
|
||||||
cur := pl.tail
|
if i == idx {
|
||||||
for i := 0; i < idx; i++ {
|
return cur
|
||||||
cur = cur.GetPrev()
|
}
|
||||||
}
|
cur = cur.next
|
||||||
return cur
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove 删除节点
|
|
||||||
func (pl *PriorityList) Remove(node INode) {
|
|
||||||
|
|
||||||
if pl.size <= 1 {
|
|
||||||
pl.head = nil
|
|
||||||
pl.tail = nil
|
|
||||||
if pl.size == 0 {
|
|
||||||
panic("the node is not in this list, node:" + spew.Sprint(node))
|
|
||||||
}
|
}
|
||||||
pl.size = 0
|
} else {
|
||||||
|
cur := pl.tail.prev
|
||||||
|
for i := -1; cur != pl.head; i-- {
|
||||||
|
if i == idx {
|
||||||
|
return cur
|
||||||
|
}
|
||||||
|
cur = cur.prev
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove 删除节点
|
||||||
|
func (pl *PriorityList) Remove(idx int) {
|
||||||
|
pl.RemoveNode(pl.GetNode(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNode 删除节点
|
||||||
|
func (pl *PriorityList) RemoveNode(node *Node) {
|
||||||
|
if node == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev := node.prev
|
||||||
|
next := node.next
|
||||||
|
|
||||||
|
prev.next = next
|
||||||
|
next.prev = prev
|
||||||
|
|
||||||
pl.size--
|
pl.size--
|
||||||
prev := node.GetPrev()
|
|
||||||
next := node.GetNext()
|
|
||||||
|
|
||||||
if prev == nil {
|
|
||||||
pl.head = next
|
|
||||||
next.SetPrev(nil)
|
|
||||||
node.SetNext(nil)
|
|
||||||
} else if next == nil {
|
|
||||||
pl.tail = prev
|
|
||||||
prev.SetNext(nil)
|
|
||||||
node.SetPrev(nil)
|
|
||||||
} else {
|
|
||||||
prev.SetNext(next)
|
|
||||||
next.SetPrev(prev)
|
|
||||||
|
|
||||||
node.SetPrev(nil)
|
|
||||||
node.SetNext(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveIndex 删除节点 并获取该节点
|
|
||||||
func (pl *PriorityList) RemoveIndex(idx int) INode {
|
|
||||||
result := pl.Get(idx)
|
|
||||||
pl.Remove(result)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveReverseIndex 逆顺序删除节点 并获取该节点
|
|
||||||
func (pl *PriorityList) RemoveReverseIndex(idx int) INode {
|
|
||||||
result := pl.GetReverse(idx)
|
|
||||||
pl.Remove(result)
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pl *PriorityList) String() string {
|
func (pl *PriorityList) String() string {
|
||||||
content := "["
|
content := "["
|
||||||
|
|
||||||
cur := pl.head
|
cur := pl.head.next
|
||||||
for cur != nil {
|
for cur != pl.tail {
|
||||||
content += spew.Sprint(cur.GetValue()) + ","
|
content += spew.Sprint(cur.Value) + ","
|
||||||
cur = cur.GetNext()
|
cur = cur.next
|
||||||
}
|
}
|
||||||
|
|
||||||
if content[len(content)-1:] == "," {
|
if content[len(content)-1:] == "," {
|
||||||
|
@ -223,48 +121,44 @@ func (pl *PriorityList) String() string {
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pl *PriorityList) Iterator() *Iterator {
|
||||||
|
return &Iterator{pl: pl, cur: pl.head}
|
||||||
|
}
|
||||||
|
|
||||||
// Insert 插入节点
|
// Insert 插入节点
|
||||||
func (pl *PriorityList) Insert(node INode) {
|
func (pl *PriorityList) Insert(value interface{}) {
|
||||||
pl.size++
|
pl.size++
|
||||||
if pl.head == nil {
|
inode := &Node{Value: value}
|
||||||
pl.head = node
|
|
||||||
pl.tail = node
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cur := pl.head
|
|
||||||
for {
|
|
||||||
if !cur.Compare(node) {
|
|
||||||
// 插入该值
|
|
||||||
prev := cur.GetPrev()
|
|
||||||
if prev == nil {
|
|
||||||
pl.head.SetPrev(node)
|
|
||||||
node.SetNext(pl.head)
|
|
||||||
pl.head = node
|
|
||||||
} else {
|
|
||||||
prev.SetNext(node)
|
|
||||||
node.SetNext(cur)
|
|
||||||
cur.SetPrev(node)
|
|
||||||
node.SetPrev(prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
cur := pl.head.next
|
||||||
|
for i := 0; cur != pl.tail; i++ {
|
||||||
|
if pl.compartor(value, cur.Value) > 0 {
|
||||||
|
prev := cur.prev
|
||||||
|
prev.next = inode
|
||||||
|
cur.prev = inode
|
||||||
|
inode.prev = prev
|
||||||
|
inode.next = cur
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
cur = cur.next
|
||||||
next := cur.GetNext()
|
|
||||||
if next == nil {
|
|
||||||
cur.SetNext(node)
|
|
||||||
node.SetPrev(cur)
|
|
||||||
pl.tail = node
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cur = next
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev := cur.prev
|
||||||
|
prev.next = inode
|
||||||
|
cur.prev = inode
|
||||||
|
inode.prev = prev
|
||||||
|
inode.next = cur
|
||||||
}
|
}
|
||||||
|
|
||||||
// New 创建 PriorityList
|
// New 创建 PriorityList
|
||||||
func New() *PriorityList {
|
func New(compartor utils.Comparator) *PriorityList {
|
||||||
return new(PriorityList)
|
pl := new(PriorityList)
|
||||||
|
pl.compartor = compartor
|
||||||
|
pl.head = new(Node)
|
||||||
|
pl.tail = new(Node)
|
||||||
|
|
||||||
|
pl.head.next = pl.tail
|
||||||
|
pl.tail.prev = pl.head
|
||||||
|
|
||||||
|
return pl
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,86 +2,41 @@ package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Pallinder/go-randomdata"
|
||||||
|
|
||||||
|
"github.com/emirpasic/gods/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPriority(t *testing.T) {
|
func TestPriority(t *testing.T) {
|
||||||
pl := New()
|
pl := New(utils.IntComparator)
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
pl.Insert(randomdata.Number(0, 100000))
|
||||||
|
}
|
||||||
|
t.Error(pl.String(), pl.Get(5), pl.Get(-1), pl.Get(-pl.size), pl.Get(-pl.size-1))
|
||||||
|
|
||||||
pl.Insert(NewNodeInt(1))
|
iter := pl.Iterator()
|
||||||
pl.Insert(NewNodeInt(2))
|
|
||||||
pl.Insert(NewNodeInt(3))
|
for iter.Next() {
|
||||||
if pl.String() != "[3,2,1]" {
|
t.Error(iter.Value())
|
||||||
t.Error("Insert or String error", pl.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if pl.Get(0).GetValue() != 3 {
|
for iter.Prev() {
|
||||||
t.Error(pl.Get(0).GetValue())
|
t.Error(iter.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
if pl.Get(pl.Size()-1).GetValue() != 1 {
|
for i := 0; i < 20; i++ {
|
||||||
t.Error(pl.Get(pl.Size() - 1).GetValue())
|
pl.Remove(0)
|
||||||
}
|
t.Error(pl.String())
|
||||||
|
|
||||||
if pl.Size() != 3 {
|
|
||||||
t.Error("size error, current is", pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.Remove(pl.Get(2))
|
|
||||||
if pl.String() != "[3,2]" || pl.Size() != 2 {
|
|
||||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.Remove(pl.GetReverse(0))
|
|
||||||
if pl.String() != "[3]" || pl.Size() != 1 {
|
|
||||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.Remove(pl.Get(0))
|
|
||||||
if pl.String() != "[]" || pl.Size() != 0 {
|
|
||||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.Insert(NewNodeInt(6))
|
|
||||||
pl.Insert(NewNodeInt(5))
|
|
||||||
pl.Insert(NewNodeInt(7))
|
|
||||||
pl.Insert(NewNodeInt(12))
|
|
||||||
pl.Insert(NewNodeInt(8))
|
|
||||||
if pl.String() != "[12,8,7,6,5]" || pl.Size() != 5 {
|
|
||||||
t.Error("Insert or String error, current is ", pl.String(), pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.RemoveReverseIndex(3)
|
|
||||||
if pl.String() != "[12,7,6,5]" || pl.Size() != 4 {
|
|
||||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
size := pl.Size()
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
pl.RemoveReverseIndex(0)
|
|
||||||
}
|
|
||||||
if pl.String() != "[]" || pl.Size() != 0 {
|
|
||||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.Insert(NewNodeInt(6))
|
|
||||||
pl.Insert(NewNodeInt(1))
|
|
||||||
pl.Insert(NewNodeInt(9))
|
|
||||||
pl.Insert(NewNodeInt(15))
|
|
||||||
pl.Insert(NewNodeInt(12))
|
|
||||||
pl.Insert(NewNodeInt(8))
|
|
||||||
|
|
||||||
if pl.GetCompare(NewNodeInt(9)).GetValue() != 9 {
|
|
||||||
t.Error(pl.String(), pl.GetCompare(NewNodeInt(9)).GetValue())
|
|
||||||
}
|
|
||||||
|
|
||||||
if pl.GetCompareReverse(NewNodeInt(11)).GetValue() != 12 {
|
|
||||||
t.Error(pl.String(), pl.GetCompareReverse(NewNodeInt(11)).GetValue())
|
|
||||||
}
|
|
||||||
|
|
||||||
pl.Clear()
|
|
||||||
|
|
||||||
if pl.String() != "[]" || pl.Size() != 0 {
|
|
||||||
t.Error("Remove error current is ", pl.String(), pl.Size())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkPriority(b *testing.B) {
|
||||||
|
pl := New(utils.IntComparator)
|
||||||
|
|
||||||
|
b.N = 10000
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
pl.Insert(randomdata.Number(0, 100000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,190 +1,82 @@
|
||||||
package plist
|
package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
"github.com/emirpasic/gods/trees/binaryheap"
|
||||||
|
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
||||||
type PriorityQueue struct {
|
type PriorityQueue struct {
|
||||||
index *Index
|
heaps []*binaryheap.Heap
|
||||||
indexlimit int
|
heapsCap int
|
||||||
node *Node
|
cursor int
|
||||||
|
|
||||||
|
splitlimit int
|
||||||
size int
|
size int
|
||||||
comparator utils.Comparator
|
comparator utils.Comparator
|
||||||
}
|
}
|
||||||
|
|
||||||
type Index struct {
|
|
||||||
node *Node
|
|
||||||
next *Index
|
|
||||||
nlen int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Node struct {
|
|
||||||
value interface{}
|
|
||||||
|
|
||||||
// prev *Node
|
|
||||||
next *Node
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithInt compare use int
|
|
||||||
func NewWithInt() *PriorityQueue {
|
|
||||||
p := new(PriorityQueue)
|
|
||||||
p.indexlimit = 10
|
|
||||||
p.comparator = func(a, b interface{}) int {
|
|
||||||
if a.(int) > b.(int) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pq *PriorityQueue) String() string {
|
func (pq *PriorityQueue) String() string {
|
||||||
|
|
||||||
content := ""
|
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 + "-"
|
for i := pq.cursor; i < pq.heapsCap; i++ {
|
||||||
content += spew.Sprint(cur.value) + "-"
|
content += spew.Sprint(pq.heaps[i].Values()) + "--"
|
||||||
}
|
}
|
||||||
|
|
||||||
if content != "" {
|
return 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pq *PriorityQueue) Push(v interface{}) {
|
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
|
||||||
|
|
||||||
node := new(Node)
|
pq.comparator = func(v1, v2 interface{}) int {
|
||||||
node.value = v
|
if v1.(int) > v2.(int) {
|
||||||
|
return 1
|
||||||
if pq.node == nil {
|
} else if v1.(int) < v2.(int) {
|
||||||
//创建索引
|
return -1
|
||||||
index := new(Index)
|
|
||||||
index.nlen = 1
|
|
||||||
index.node = node
|
|
||||||
|
|
||||||
pq.index = index
|
|
||||||
pq.node = node
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// find the node of index to start
|
|
||||||
idx := pq.index
|
|
||||||
|
|
||||||
for {
|
|
||||||
|
|
||||||
if idx.next == nil {
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
return 0
|
||||||
if pq.comparator(v, idx.next.node.value) > 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = idx.next
|
|
||||||
}
|
}
|
||||||
|
pq.heaps[pq.cursor] = binaryheap.NewWith(pq.comparator)
|
||||||
|
return pq
|
||||||
|
}
|
||||||
|
|
||||||
cur := idx.node
|
func (pq *PriorityQueue) Push(value interface{}) {
|
||||||
|
|
||||||
//cur := pq.node
|
|
||||||
if pq.comparator(v, pq.node.value) > 0 {
|
|
||||||
pq.node = node
|
|
||||||
node.next = cur
|
|
||||||
|
|
||||||
pq.index.node = pq.node
|
|
||||||
pq.index.nlen++
|
|
||||||
|
|
||||||
// cur.prev = node
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; cur.next != nil; i++ {
|
|
||||||
|
|
||||||
if i >= pq.indexlimit {
|
|
||||||
|
|
||||||
if idx.next != nil && idx.next.nlen < pq.indexlimit {
|
|
||||||
idx.next.nlen += idx.nlen - pq.indexlimit
|
|
||||||
idx.nlen = pq.indexlimit
|
|
||||||
idx.next.node = cur
|
|
||||||
} else {
|
|
||||||
index := new(Index)
|
|
||||||
index.node = cur
|
|
||||||
index.nlen = idx.nlen - pq.indexlimit
|
|
||||||
index.next = idx.next
|
|
||||||
|
|
||||||
idx.next = index
|
|
||||||
idx.nlen = pq.indexlimit
|
|
||||||
idx = index
|
|
||||||
i = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if pq.comparator(v, cur.next.value) > 0 {
|
|
||||||
temp := cur.next
|
|
||||||
cur.next = node
|
|
||||||
node.next = temp
|
|
||||||
// node.prev = cur
|
|
||||||
// temp.prev = node
|
|
||||||
|
|
||||||
idx.nlen++
|
|
||||||
|
|
||||||
// if pq.index.nlen >= pq.indexlimit {
|
|
||||||
// // 分裂
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = cur.next
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cur.next = node
|
|
||||||
|
|
||||||
// node.prev = cur
|
|
||||||
pq.size++
|
pq.size++
|
||||||
idx.nlen++
|
|
||||||
|
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?"))
|
||||||
|
}
|
||||||
|
heap.Push(v)
|
||||||
|
}
|
||||||
|
pq.heaps[pq.cursor] = heap
|
||||||
|
|
||||||
|
} else {
|
||||||
|
curheap.Push(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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]
|
|
||||||
// }
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package plist
|
package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/emirpasic/gods/trees/avltree"
|
||||||
|
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
|
|
||||||
"github.com/Pallinder/go-randomdata"
|
"github.com/Pallinder/go-randomdata"
|
||||||
|
@ -11,56 +12,76 @@ import (
|
||||||
"github.com/emirpasic/gods/trees/binaryheap"
|
"github.com/emirpasic/gods/trees/binaryheap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PriorityQ struct {
|
func TestPQ(t *testing.T) {
|
||||||
heap *binaryheap.Heap
|
|
||||||
comparator utils.Comparator
|
|
||||||
topk int
|
|
||||||
next *PriorityQ
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pq *PriorityQ) Push(v interface{}) {
|
var l []int
|
||||||
}
|
pq := NewWithIntComparator()
|
||||||
|
for i := 0; i < 50; i++ {
|
||||||
func TestNPQ(t *testing.T) {
|
v := randomdata.Number(0, 1000)
|
||||||
h1 := binaryheap.NewWithIntComparator()
|
pq.Push(v)
|
||||||
|
l = append(l, v)
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
h1.Push(i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1.Values()[0] = 3
|
// iter := pq.avl.Iterator()
|
||||||
|
// iter.Next()
|
||||||
log.Println(h1)
|
// pl := iter.Value().(*PriorityList)
|
||||||
|
// t.Error(pq.size, "avlsize:", pq.avl.Size(), pl.Size(), pl.head == nil, pl.String())
|
||||||
|
|
||||||
|
t.Error(l)
|
||||||
|
t.Error(pq.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPriorityQueue(t *testing.T) {
|
func BenchmarkPQ(b *testing.B) {
|
||||||
p := NewWithInt()
|
|
||||||
|
|
||||||
for i := 0; i < 100; i++ {
|
// b.Log("all:", pq.avl.Size(), pq.avl.Values())
|
||||||
p.Push(randomdata.Number(0, 10000))
|
}
|
||||||
t.Log(p.String())
|
|
||||||
|
func TestAvl(t *testing.T) {
|
||||||
|
|
||||||
|
comparator := func(v1, v2 interface{}) int {
|
||||||
|
if v1.(int) > v2.(int) {
|
||||||
|
return 1
|
||||||
|
} else if v1.(int) < v2.(int) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Error(p.String())
|
avl := avltree.NewWith(comparator)
|
||||||
}
|
for _, v := range []int{9, 2, 3, 4, 5, 6, 8, 1} {
|
||||||
|
avl.Put(v, v)
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkPriorityQueue(b *testing.B) {
|
iter := avl.Iterator()
|
||||||
p := NewWithInt()
|
iter.End()
|
||||||
|
iter.Prev()
|
||||||
|
t.Error(avl.Values(), iter.Value())
|
||||||
|
|
||||||
// for i := 0; i < 10000; i++ {
|
f, ok := avl.Floor(10)
|
||||||
// p.Push(randomdata.Number(0, 100000))
|
if ok {
|
||||||
// // p.Values()
|
t.Error("Floor", f)
|
||||||
// }
|
}
|
||||||
|
|
||||||
b.N = 100000
|
f, ok = avl.Ceiling(10)
|
||||||
for i := 0; i < b.N; i++ {
|
if ok {
|
||||||
p.Push(randomdata.Number(0, 100000))
|
t.Error("Ceiling", f)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range []int{9, 2, 3, 45, 51, 16, 18, 11} {
|
||||||
|
avl.Put(v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = avl.Iterator()
|
||||||
|
iter.End()
|
||||||
|
|
||||||
|
for iter.Prev() {
|
||||||
|
t.Error(iter.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHeap(t *testing.T) {
|
func TestHeap(t *testing.T) {
|
||||||
|
|
||||||
heap := binaryheap.NewWithIntComparator()
|
heap := binaryheap.NewWithIntComparator()
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
|
@ -73,35 +94,3 @@ func TestHeap(t *testing.T) {
|
||||||
utils.Sort(heap.Values(), utils.IntComparator)
|
utils.Sort(heap.Values(), utils.IntComparator)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkList_InsertValues123(b *testing.B) {
|
|
||||||
a := func(v1, v2 interface{}) int {
|
|
||||||
if v1.(int) > v2.(int) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
h := binaryheap.NewWith(a)
|
|
||||||
|
|
||||||
TOPK := 50
|
|
||||||
|
|
||||||
for i := 0; i < TOPK*1000; i++ {
|
|
||||||
h.Push(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.StartTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
h.Push(i)
|
|
||||||
l := []interface{}{}
|
|
||||||
for n := 0; n < TOPK; n++ {
|
|
||||||
v, _ := h.Pop()
|
|
||||||
l = append(l, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range l {
|
|
||||||
h.Push(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.StopTimer()
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user