diff --git a/priority_queue/avltree.go b/priority_queue/avltree.go new file mode 100644 index 0000000..4d80061 --- /dev/null +++ b/priority_queue/avltree.go @@ -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) + } +} diff --git a/priority_queue/iterator.go b/priority_queue/iterator.go new file mode 100644 index 0000000..da9d9cb --- /dev/null +++ b/priority_queue/iterator.go @@ -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() +} diff --git a/priority_queue/priority_queue.go b/priority_queue/priority_queue.go index 5d6e305..af6fba0 100644 --- a/priority_queue/priority_queue.go +++ b/priority_queue/priority_queue.go @@ -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) diff --git a/priority_queue/priority_queue_test.go b/priority_queue/priority_queue_test.go index 0765dd3..2521427 100644 --- a/priority_queue/priority_queue_test.go +++ b/priority_queue/priority_queue_test.go @@ -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()