put 修改为put后返回put的节点
This commit is contained in:
parent
cd40d47a3c
commit
b5498a257b
455
priority_queue/avltree.go
Normal file
455
priority_queue/avltree.go
Normal file
@ -0,0 +1,455 @@
|
||||
// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package avltree implements an AVL balanced binary tree.
|
||||
//
|
||||
// Structure is not thread safe.
|
||||
//
|
||||
// References: https://en.wikipedia.org/wiki/AVL_tree
|
||||
package plist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/emirpasic/gods/trees"
|
||||
"github.com/emirpasic/gods/utils"
|
||||
)
|
||||
|
||||
func assertTreeImplementation() {
|
||||
var _ trees.Tree = new(Tree)
|
||||
}
|
||||
|
||||
// Tree holds elements of the AVL tree.
|
||||
type Tree struct {
|
||||
Root *ANode // Root node
|
||||
Comparator utils.Comparator // Key comparator
|
||||
size int // Total number of keys in the tree
|
||||
}
|
||||
|
||||
// ANode is a single element within the tree
|
||||
type ANode struct {
|
||||
Key interface{}
|
||||
Value interface{}
|
||||
Parent *ANode // Parent node
|
||||
Children [2]*ANode // Children nodes
|
||||
b int8
|
||||
}
|
||||
|
||||
// NewWith instantiates an AVL tree with the custom comparator.
|
||||
func NewWith(comparator utils.Comparator) *Tree {
|
||||
return &Tree{Comparator: comparator}
|
||||
}
|
||||
|
||||
// NewWithIntComparator instantiates an AVL tree with the IntComparator, i.e. keys are of type int.
|
||||
func NewWithIntComparator() *Tree {
|
||||
return &Tree{Comparator: utils.IntComparator}
|
||||
}
|
||||
|
||||
// NewWithStringComparator instantiates an AVL tree with the StringComparator, i.e. keys are of type string.
|
||||
func NewWithStringComparator() *Tree {
|
||||
return &Tree{Comparator: utils.StringComparator}
|
||||
}
|
||||
|
||||
// Put inserts node into the tree.
|
||||
// Key should adhere to the comparator's type assertion, otherwise method panics.
|
||||
func (t *Tree) Put(key interface{}, value interface{}) (bool, *ANode) {
|
||||
return t.put(key, value, nil, &t.Root)
|
||||
}
|
||||
|
||||
// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.
|
||||
// Second return parameter is true if key was found, otherwise false.
|
||||
// Key should adhere to the comparator's type assertion, otherwise method panics.
|
||||
func (t *Tree) Get(key interface{}) (value interface{}, found bool) {
|
||||
n := t.Root
|
||||
for n != nil {
|
||||
cmp := t.Comparator(key, n.Key)
|
||||
switch {
|
||||
case cmp == 0:
|
||||
return n.Value, true
|
||||
case cmp < 0:
|
||||
n = n.Children[0]
|
||||
case cmp > 0:
|
||||
n = n.Children[1]
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Remove remove the node from the tree by key.
|
||||
// Key should adhere to the comparator's type assertion, otherwise method panics.
|
||||
func (t *Tree) Remove(key interface{}) {
|
||||
t.remove(key, &t.Root)
|
||||
}
|
||||
|
||||
// Empty returns true if tree does not contain any nodes.
|
||||
func (t *Tree) Empty() bool {
|
||||
return t.size == 0
|
||||
}
|
||||
|
||||
// Size returns the number of elements stored in the tree.
|
||||
func (t *Tree) Size() int {
|
||||
return t.size
|
||||
}
|
||||
|
||||
// Keys returns all keys in-order
|
||||
func (t *Tree) Keys() []interface{} {
|
||||
keys := make([]interface{}, t.size)
|
||||
it := t.Iterator()
|
||||
for i := 0; it.Next(); i++ {
|
||||
keys[i] = it.Key()
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Values returns all values in-order based on the key.
|
||||
func (t *Tree) Values() []interface{} {
|
||||
values := make([]interface{}, t.size)
|
||||
it := t.Iterator()
|
||||
for i := 0; it.Next(); i++ {
|
||||
values[i] = it.Value()
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// Left returns the minimum element of the AVL tree
|
||||
// or nil if the tree is empty.
|
||||
func (t *Tree) Left() *ANode {
|
||||
return t.bottom(0)
|
||||
}
|
||||
|
||||
// Right returns the maximum element of the AVL tree
|
||||
// or nil if the tree is empty.
|
||||
func (t *Tree) Right() *ANode {
|
||||
return t.bottom(1)
|
||||
}
|
||||
|
||||
// Floor Finds floor node of the input key, return the floor node or nil if no ceiling is found.
|
||||
// Second return parameter is true if floor was found, otherwise false.
|
||||
//
|
||||
// Floor node is defined as the largest node that is smaller than or equal to the given node.
|
||||
// A floor node may not be found, either because the tree is empty, or because
|
||||
// all nodes in the tree is larger than the given node.
|
||||
//
|
||||
// Key should adhere to the comparator's type assertion, otherwise method panics.
|
||||
func (t *Tree) Floor(key interface{}) (floor *ANode, found bool) {
|
||||
found = false
|
||||
n := t.Root
|
||||
last := n
|
||||
|
||||
for n != nil {
|
||||
c := t.Comparator(key, n.Key)
|
||||
switch {
|
||||
case c == 0:
|
||||
return n, true
|
||||
case c < 0:
|
||||
last = n
|
||||
n = n.Children[0]
|
||||
case c > 0:
|
||||
floor, found = n, true
|
||||
n = n.Children[1]
|
||||
}
|
||||
}
|
||||
if found {
|
||||
return
|
||||
}
|
||||
return last, false
|
||||
}
|
||||
|
||||
// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
|
||||
// Second return parameter is true if ceiling was found, otherwise false.
|
||||
//
|
||||
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
|
||||
// A ceiling node may not be found, either because the tree is empty, or because
|
||||
// all nodes in the tree is smaller than the given node.
|
||||
//
|
||||
// Key should adhere to the comparator's type assertion, otherwise method panics.
|
||||
func (t *Tree) Ceiling(key interface{}) (floor *ANode, found bool) {
|
||||
found = false
|
||||
n := t.Root
|
||||
last := n
|
||||
for n != nil {
|
||||
c := t.Comparator(key, n.Key)
|
||||
switch {
|
||||
case c == 0:
|
||||
return n, true
|
||||
case c < 0:
|
||||
floor, found = n, true
|
||||
n = n.Children[0]
|
||||
case c > 0:
|
||||
last = n
|
||||
n = n.Children[1]
|
||||
}
|
||||
}
|
||||
if found {
|
||||
return
|
||||
}
|
||||
return last, false
|
||||
}
|
||||
|
||||
// Clear removes all nodes from the tree.
|
||||
func (t *Tree) Clear() {
|
||||
t.Root = nil
|
||||
t.size = 0
|
||||
}
|
||||
|
||||
// String returns a string representation of container
|
||||
func (t *Tree) String() string {
|
||||
str := "AVLTree\n"
|
||||
if !t.Empty() {
|
||||
output(t.Root, "", true, &str)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func (n *ANode) String() string {
|
||||
return fmt.Sprintf("%v", n.Key)
|
||||
}
|
||||
|
||||
func (t *Tree) put(key interface{}, value interface{}, p *ANode, qp **ANode) (bool, *ANode) {
|
||||
q := *qp
|
||||
if q == nil {
|
||||
t.size++
|
||||
*qp = &ANode{Key: key, Value: value, Parent: p}
|
||||
return true, *qp
|
||||
}
|
||||
|
||||
c := t.Comparator(key, q.Key)
|
||||
if c == 0 {
|
||||
q.Key = key
|
||||
q.Value = value
|
||||
return false, q
|
||||
}
|
||||
|
||||
if c < 0 {
|
||||
c = -1
|
||||
} else {
|
||||
c = 1
|
||||
}
|
||||
a := (c + 1) / 2
|
||||
var fix bool
|
||||
fix, node := t.put(key, value, q, &q.Children[a])
|
||||
if fix {
|
||||
return putFix(int8(c), qp), *qp
|
||||
}
|
||||
return false, q
|
||||
}
|
||||
|
||||
func (t *Tree) remove(key interface{}, qp **ANode) bool {
|
||||
q := *qp
|
||||
if q == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
c := t.Comparator(key, q.Key)
|
||||
if c == 0 {
|
||||
t.size--
|
||||
if q.Children[1] == nil {
|
||||
if q.Children[0] != nil {
|
||||
q.Children[0].Parent = q.Parent
|
||||
}
|
||||
*qp = q.Children[0]
|
||||
return true
|
||||
}
|
||||
fix := removeMin(&q.Children[1], &q.Key, &q.Value)
|
||||
if fix {
|
||||
return removeFix(-1, qp)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if c < 0 {
|
||||
c = -1
|
||||
} else {
|
||||
c = 1
|
||||
}
|
||||
a := (c + 1) / 2
|
||||
fix := t.remove(key, &q.Children[a])
|
||||
if fix {
|
||||
return removeFix(int8(-c), qp)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func removeMin(qp **ANode, minKey *interface{}, minVal *interface{}) bool {
|
||||
q := *qp
|
||||
if q.Children[0] == nil {
|
||||
*minKey = q.Key
|
||||
*minVal = q.Value
|
||||
if q.Children[1] != nil {
|
||||
q.Children[1].Parent = q.Parent
|
||||
}
|
||||
*qp = q.Children[1]
|
||||
return true
|
||||
}
|
||||
fix := removeMin(&q.Children[0], minKey, minVal)
|
||||
if fix {
|
||||
return removeFix(1, qp)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func putFix(c int8, t **ANode) bool {
|
||||
s := *t
|
||||
if s.b == 0 {
|
||||
s.b = c
|
||||
return true
|
||||
}
|
||||
|
||||
if s.b == -c {
|
||||
s.b = 0
|
||||
return false
|
||||
}
|
||||
|
||||
if s.Children[(c+1)/2].b == c {
|
||||
s = singlerot(c, s)
|
||||
} else {
|
||||
s = doublerot(c, s)
|
||||
}
|
||||
*t = s
|
||||
return false
|
||||
}
|
||||
|
||||
func removeFix(c int8, t **ANode) bool {
|
||||
s := *t
|
||||
if s.b == 0 {
|
||||
s.b = c
|
||||
return false
|
||||
}
|
||||
|
||||
if s.b == -c {
|
||||
s.b = 0
|
||||
return true
|
||||
}
|
||||
|
||||
a := (c + 1) / 2
|
||||
if s.Children[a].b == 0 {
|
||||
s = rotate(c, s)
|
||||
s.b = -c
|
||||
*t = s
|
||||
return false
|
||||
}
|
||||
|
||||
if s.Children[a].b == c {
|
||||
s = singlerot(c, s)
|
||||
} else {
|
||||
s = doublerot(c, s)
|
||||
}
|
||||
*t = s
|
||||
return true
|
||||
}
|
||||
|
||||
func singlerot(c int8, s *ANode) *ANode {
|
||||
s.b = 0
|
||||
s = rotate(c, s)
|
||||
s.b = 0
|
||||
return s
|
||||
}
|
||||
|
||||
func doublerot(c int8, s *ANode) *ANode {
|
||||
a := (c + 1) / 2
|
||||
r := s.Children[a]
|
||||
s.Children[a] = rotate(-c, s.Children[a])
|
||||
p := rotate(c, s)
|
||||
|
||||
switch {
|
||||
default:
|
||||
s.b = 0
|
||||
r.b = 0
|
||||
case p.b == c:
|
||||
s.b = -c
|
||||
r.b = 0
|
||||
case p.b == -c:
|
||||
s.b = 0
|
||||
r.b = c
|
||||
}
|
||||
|
||||
p.b = 0
|
||||
return p
|
||||
}
|
||||
|
||||
func rotate(c int8, s *ANode) *ANode {
|
||||
a := (c + 1) / 2
|
||||
r := s.Children[a]
|
||||
s.Children[a] = r.Children[a^1]
|
||||
if s.Children[a] != nil {
|
||||
s.Children[a].Parent = s
|
||||
}
|
||||
r.Children[a^1] = s
|
||||
r.Parent = s.Parent
|
||||
s.Parent = r
|
||||
return r
|
||||
}
|
||||
|
||||
func (t *Tree) bottom(d int) *ANode {
|
||||
n := t.Root
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for c := n.Children[d]; c != nil; c = n.Children[d] {
|
||||
n = c
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Prev returns the previous element in an inorder
|
||||
// walk of the AVL tree.
|
||||
func (n *ANode) Prev() *ANode {
|
||||
return n.walk1(0)
|
||||
}
|
||||
|
||||
// Next returns the next element in an inorder
|
||||
// walk of the AVL tree.
|
||||
func (n *ANode) Next() *ANode {
|
||||
return n.walk1(1)
|
||||
}
|
||||
|
||||
func (n *ANode) walk1(a int) *ANode {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if n.Children[a] != nil {
|
||||
n = n.Children[a]
|
||||
for n.Children[a^1] != nil {
|
||||
n = n.Children[a^1]
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
p := n.Parent
|
||||
for p != nil && p.Children[a] == n {
|
||||
n = p
|
||||
p = p.Parent
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func output(node *ANode, prefix string, isTail bool, str *string) {
|
||||
if node.Children[1] != nil {
|
||||
newPrefix := prefix
|
||||
if isTail {
|
||||
newPrefix += "│ "
|
||||
} else {
|
||||
newPrefix += " "
|
||||
}
|
||||
output(node.Children[1], newPrefix, false, str)
|
||||
}
|
||||
*str += prefix
|
||||
if isTail {
|
||||
*str += "└── "
|
||||
} else {
|
||||
*str += "┌── "
|
||||
}
|
||||
*str += node.String() + "\n"
|
||||
if node.Children[0] != nil {
|
||||
newPrefix := prefix
|
||||
if isTail {
|
||||
newPrefix += " "
|
||||
} else {
|
||||
newPrefix += "│ "
|
||||
}
|
||||
output(node.Children[0], newPrefix, true, str)
|
||||
}
|
||||
}
|
117
priority_queue/iterator.go
Normal file
117
priority_queue/iterator.go
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package plist
|
||||
|
||||
import "github.com/emirpasic/gods/containers"
|
||||
|
||||
func assertIteratorImplementation() {
|
||||
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
|
||||
}
|
||||
|
||||
// Iterator holding the iterator's state
|
||||
type Iterator struct {
|
||||
tree *Tree
|
||||
node *ANode
|
||||
position position
|
||||
}
|
||||
|
||||
type position byte
|
||||
|
||||
const (
|
||||
begin, between, end position = 0, 1, 2
|
||||
)
|
||||
|
||||
// Iterator returns a stateful iterator whose elements are key/value pairs.
|
||||
func (tree *Tree) Iterator() containers.ReverseIteratorWithKey {
|
||||
return &Iterator{tree: tree, node: nil, position: begin}
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
switch iterator.position {
|
||||
case begin:
|
||||
iterator.position = between
|
||||
iterator.node = iterator.tree.Left()
|
||||
case between:
|
||||
iterator.node = iterator.node.Next()
|
||||
}
|
||||
|
||||
if iterator.node == nil {
|
||||
iterator.position = end
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Prev moves the iterator to the next element and returns true if there was a previous element in the container.
|
||||
// If Prev() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||
// If Prev() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Prev() bool {
|
||||
switch iterator.position {
|
||||
case end:
|
||||
iterator.position = between
|
||||
iterator.node = iterator.tree.Right()
|
||||
case between:
|
||||
iterator.node = iterator.node.Prev()
|
||||
}
|
||||
|
||||
if iterator.node == nil {
|
||||
iterator.position = begin
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Value returns the current element's value.
|
||||
// Does not modify the state of the iterator.
|
||||
func (iterator *Iterator) Value() interface{} {
|
||||
if iterator.node == nil {
|
||||
return nil
|
||||
}
|
||||
return iterator.node.Value
|
||||
}
|
||||
|
||||
// Key returns the current element's key.
|
||||
// Does not modify the state of the iterator.
|
||||
func (iterator *Iterator) Key() interface{} {
|
||||
if iterator.node == nil {
|
||||
return nil
|
||||
}
|
||||
return iterator.node.Key
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.node = nil
|
||||
iterator.position = begin
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.node = nil
|
||||
iterator.position = end
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
||||
type PriorityQueue struct {
|
||||
avlIndex *avltree.Tree
|
||||
index *avltree.Tree
|
||||
indexlimit int
|
||||
|
||||
node *Node
|
||||
@ -34,7 +34,7 @@ func NewWithInt() *PriorityQueue {
|
||||
}
|
||||
|
||||
p.indexlimit = 10
|
||||
p.avlIndex = avltree.NewWith(p.comparator)
|
||||
p.index = avltree.NewWith(p.comparator)
|
||||
|
||||
return p
|
||||
}
|
||||
@ -50,129 +50,102 @@ func (pq *PriorityQueue) String() string {
|
||||
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
|
||||
return content
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) findIndexStart(v interface{}) *Index {
|
||||
// find the node of index to start
|
||||
idx := pq.index
|
||||
for {
|
||||
if idx.next == nil {
|
||||
break
|
||||
}
|
||||
// func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
|
||||
// if index < 0 || index >= pq.size {
|
||||
// return nil, false
|
||||
// }
|
||||
|
||||
if pq.comparator(v, idx.next.node.value) > 0 {
|
||||
break
|
||||
}
|
||||
// idx := pq.index
|
||||
// movesize := index
|
||||
// for {
|
||||
// if movesize-idx.nlen <= 0 {
|
||||
// break
|
||||
// } else {
|
||||
// movesize -= idx.nlen
|
||||
// idx = idx.next
|
||||
// }
|
||||
// }
|
||||
|
||||
idx = idx.next
|
||||
}
|
||||
return idx
|
||||
}
|
||||
// cur := idx.node
|
||||
// for movesize > 0 {
|
||||
// movesize--
|
||||
// cur = cur.next
|
||||
// }
|
||||
|
||||
func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
|
||||
if index < 0 || index >= pq.size {
|
||||
return nil, false
|
||||
}
|
||||
// return cur.value, true
|
||||
// }
|
||||
|
||||
idx := pq.index
|
||||
movesize := index
|
||||
for {
|
||||
if movesize-idx.nlen <= 0 {
|
||||
break
|
||||
} else {
|
||||
movesize -= idx.nlen
|
||||
idx = idx.next
|
||||
}
|
||||
}
|
||||
// func (pq *PriorityQueue) Push(v interface{}) {
|
||||
|
||||
cur := idx.node
|
||||
for movesize > 0 {
|
||||
movesize--
|
||||
cur = cur.next
|
||||
}
|
||||
// node := &Node{value: v}
|
||||
// pq.size++
|
||||
|
||||
return cur.value, true
|
||||
}
|
||||
// if pq.node == nil {
|
||||
// //创建索引
|
||||
// pq.index.Put(node, 1)
|
||||
|
||||
func (pq *PriorityQueue) Push(v interface{}) {
|
||||
// pq.node = node
|
||||
// return
|
||||
// }
|
||||
// // find the node of index to start
|
||||
// fool, ok := pq.index.Ceiling(v)
|
||||
// cur := idx.node
|
||||
|
||||
node := new(Node)
|
||||
node.value = v
|
||||
pq.size++
|
||||
// if pq.comparator(v, pq.node.value) > 0 {
|
||||
// pq.node = node
|
||||
// node.next = cur
|
||||
|
||||
if pq.node == nil {
|
||||
//创建索引
|
||||
index := new(Index)
|
||||
index.nlen = 1
|
||||
index.node = node
|
||||
// pq.index.node = pq.node
|
||||
// pq.index.nlen++
|
||||
// return
|
||||
// }
|
||||
|
||||
pq.index = index
|
||||
pq.node = node
|
||||
return
|
||||
}
|
||||
// find the node of index to start
|
||||
idx := pq.findIndexStart(v)
|
||||
cur := idx.node
|
||||
// for i := 0; cur.next != nil; i++ {
|
||||
|
||||
if pq.comparator(v, pq.node.value) > 0 {
|
||||
pq.node = node
|
||||
node.next = cur
|
||||
// // 分裂和整理索引
|
||||
// if i >= pq.indexlimit {
|
||||
|
||||
pq.index.node = pq.node
|
||||
pq.index.nlen++
|
||||
return
|
||||
}
|
||||
// if idx.next != nil && idx.next.nlen < pq.indexlimit {
|
||||
// idx.next.nlen += idx.nlen - pq.indexlimit
|
||||
// idx.nlen = pq.indexlimit
|
||||
// idx.next.node = cur
|
||||
// idx = idx.next
|
||||
// } else {
|
||||
// index := new(Index)
|
||||
// index.node = cur
|
||||
// index.nlen = idx.nlen - pq.indexlimit
|
||||
// index.next = idx.next
|
||||
|
||||
for i := 0; cur.next != nil; i++ {
|
||||
// idx.next = index
|
||||
// idx.nlen = pq.indexlimit
|
||||
// idx = index
|
||||
// }
|
||||
|
||||
// 分裂和整理索引
|
||||
if i >= pq.indexlimit {
|
||||
// i = 0
|
||||
// }
|
||||
|
||||
if idx.next != nil && idx.next.nlen < pq.indexlimit {
|
||||
idx.next.nlen += idx.nlen - pq.indexlimit
|
||||
idx.nlen = pq.indexlimit
|
||||
idx.next.node = cur
|
||||
idx = idx.next
|
||||
} else {
|
||||
index := new(Index)
|
||||
index.node = cur
|
||||
index.nlen = idx.nlen - pq.indexlimit
|
||||
index.next = idx.next
|
||||
// if pq.comparator(v, cur.next.value) > 0 {
|
||||
// temp := cur.next
|
||||
// cur.next = node
|
||||
// node.next = temp
|
||||
// idx.nlen++
|
||||
// return
|
||||
// }
|
||||
// cur = cur.next
|
||||
|
||||
idx.next = index
|
||||
idx.nlen = pq.indexlimit
|
||||
idx = index
|
||||
}
|
||||
// }
|
||||
|
||||
i = 0
|
||||
}
|
||||
// cur.next = node
|
||||
// idx.nlen++
|
||||
|
||||
if pq.comparator(v, cur.next.value) > 0 {
|
||||
temp := cur.next
|
||||
cur.next = node
|
||||
node.next = temp
|
||||
idx.nlen++
|
||||
return
|
||||
}
|
||||
cur = cur.next
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
cur.next = node
|
||||
idx.nlen++
|
||||
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Top() (interface{}, bool) {
|
||||
return pq.Get(0)
|
||||
}
|
||||
// func (pq *PriorityQueue) Top() (interface{}, bool) {
|
||||
// return pq.Get(0)
|
||||
// }
|
||||
|
||||
// func (pq *PriorityQueue) Bottom() (interface{}, bool) {
|
||||
// return pq.Get(pq.right - 1)
|
||||
|
@ -3,8 +3,6 @@ package plist
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/emirpasic/gods/trees/avltree"
|
||||
|
||||
"github.com/emirpasic/gods/utils"
|
||||
|
||||
"github.com/Pallinder/go-randomdata"
|
||||
@ -12,86 +10,95 @@ import (
|
||||
"github.com/emirpasic/gods/trees/binaryheap"
|
||||
)
|
||||
|
||||
func TestGetPriorityQueue(t *testing.T) {
|
||||
p := NewWithInt()
|
||||
// func TestGetPriorityQueue(t *testing.T) {
|
||||
// p := NewWithInt()
|
||||
|
||||
var l []int
|
||||
for i := 0; i < 10; i++ {
|
||||
l = append(l, randomdata.Number(0, 10000))
|
||||
}
|
||||
// var l []int
|
||||
// for i := 0; i < 10; i++ {
|
||||
// l = append(l, randomdata.Number(0, 10000))
|
||||
// }
|
||||
|
||||
for _, v := range l {
|
||||
p.Push(v)
|
||||
t.Log(p.String())
|
||||
}
|
||||
// for _, v := range l {
|
||||
// p.Push(v)
|
||||
// t.Log(p.String())
|
||||
// }
|
||||
|
||||
t.Error(l)
|
||||
t.Error(p.String())
|
||||
// t.Error(l)
|
||||
// t.Error(p.String())
|
||||
|
||||
for _, i := range []int{-1, 0, p.size / 2, p.size - 1, p.size} {
|
||||
v, ok := p.Get(i)
|
||||
t.Error(i, v, ok)
|
||||
}
|
||||
// for _, i := range []int{-1, 0, p.size / 2, p.size - 1, p.size} {
|
||||
// v, ok := p.Get(i)
|
||||
// t.Error(i, v, ok)
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
func TestPustPriorityQueue(t *testing.T) {
|
||||
p := NewWithInt()
|
||||
// func TestPustPriorityQueue(t *testing.T) {
|
||||
// p := NewWithInt()
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
p.Push(randomdata.Number(0, 10000))
|
||||
t.Log(p.String())
|
||||
}
|
||||
// for i := 0; i < 100; i++ {
|
||||
// p.Push(randomdata.Number(0, 10000))
|
||||
// t.Log(p.String())
|
||||
// }
|
||||
|
||||
t.Error(p.String())
|
||||
}
|
||||
// t.Error(p.String())
|
||||
// }
|
||||
|
||||
func BenchmarkPriorityQueuePush(b *testing.B) {
|
||||
p := NewWithInt()
|
||||
// func BenchmarkPriorityQueuePush(b *testing.B) {
|
||||
// p := NewWithInt()
|
||||
|
||||
// for i := 0; i < 10000; i++ {
|
||||
// p.Push(randomdata.Number(0, 100000))
|
||||
// // p.Values()
|
||||
// }
|
||||
// // for i := 0; i < 10000; i++ {
|
||||
// // p.Push(randomdata.Number(0, 100000))
|
||||
// // // p.Values()
|
||||
// // }
|
||||
|
||||
b.N = 10000
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.Push(randomdata.Number(0, 100000))
|
||||
}
|
||||
// b.N = 10000
|
||||
// for i := 0; i < b.N; i++ {
|
||||
// p.Push(randomdata.Number(0, 100000))
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
func BenchmarkPriorityQueueGet(b *testing.B) {
|
||||
p := NewWithInt()
|
||||
// func BenchmarkPriorityQueueGet(b *testing.B) {
|
||||
// p := NewWithInt()
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
p.Push(randomdata.Number(0, 100000))
|
||||
// p.Values()
|
||||
}
|
||||
// for i := 0; i < 10000; i++ {
|
||||
// p.Push(randomdata.Number(0, 100000))
|
||||
// // p.Values()
|
||||
// }
|
||||
|
||||
b.StartTimer()
|
||||
b.N = 100000
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.Get(randomdata.Number(0, 10000))
|
||||
}
|
||||
b.StopTimer()
|
||||
// b.StartTimer()
|
||||
// b.N = 100000
|
||||
// for i := 0; i < b.N; i++ {
|
||||
// p.Get(randomdata.Number(0, 10000))
|
||||
// }
|
||||
// b.StopTimer()
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
func TestAVL(t *testing.T) {
|
||||
avl := avltree.NewWithIntComparator()
|
||||
for i := 0; i < 10; i++ {
|
||||
v := randomdata.Number(0, 10)
|
||||
avl.Put(v, v)
|
||||
avl := NewWithIntComparator()
|
||||
for i := 0; i < 100; i++ {
|
||||
v := randomdata.Number(0, 100)
|
||||
ok, n := avl.Put(v, v)
|
||||
t.Error(v, ok, n)
|
||||
}
|
||||
t.Error(avl.Values())
|
||||
f, ok := avl.Ceiling(100)
|
||||
f, ok := avl.Ceiling(1000)
|
||||
t.Error(f, ok)
|
||||
t.Error(f.Next().Value)
|
||||
if ok {
|
||||
t.Error(f.Next().Value)
|
||||
}
|
||||
|
||||
f, ok = avl.Floor(-1)
|
||||
t.Error(f, ok)
|
||||
if ok {
|
||||
t.Error(f.Next().Value)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAVL(b *testing.B) {
|
||||
avl := avltree.NewWithIntComparator()
|
||||
avl := NewWithIntComparator()
|
||||
b.N = 1000000
|
||||
|
||||
b.StartTimer()
|
||||
|
Loading…
x
Reference in New Issue
Block a user