TODO: avlkey
This commit is contained in:
@@ -57,6 +57,10 @@ func (avl *AVL) Iterator() *Iterator {
|
||||
return initIterator(avl)
|
||||
}
|
||||
|
||||
func (avl *AVL) Size() int {
|
||||
return avl.size
|
||||
}
|
||||
|
||||
func (avl *AVL) Remove(v interface{}) *Node {
|
||||
|
||||
if n, ok := avl.GetNode(v); ok {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package avl
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/emirpasic/gods/maps/hashmap"
|
||||
"github.com/emirpasic/gods/trees/redblacktree"
|
||||
|
||||
"github.com/emirpasic/gods/trees/avltree"
|
||||
@@ -347,7 +349,31 @@ func BenchmarkGodsRemove(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGoGet(b *testing.B) {
|
||||
avl := make(map[int]int)
|
||||
|
||||
b.N = CompartorSize
|
||||
for i := 0; i < b.N; i++ {
|
||||
avl[randomdata.Number(0, NumberMax)] = i
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
b.N = CompartorSize
|
||||
|
||||
var v int
|
||||
var ok bool
|
||||
for i := 0; i < b.N; i++ {
|
||||
v, ok = avl[randomdata.Number(0, NumberMax)]
|
||||
}
|
||||
|
||||
if ok && v == 1 {
|
||||
v = 1
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGet(b *testing.B) {
|
||||
|
||||
avl := New(utils.IntComparator)
|
||||
|
||||
b.N = CompartorSize
|
||||
@@ -392,6 +418,41 @@ func BenchmarkGodsAvlGet(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGoPut(b *testing.B) {
|
||||
avl := make(map[int]int)
|
||||
|
||||
for i := 0; i < 100000; i++ {
|
||||
avl[randomdata.Number(0, NumberMax)] = i
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
b.N = CompartorSize
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
avl[randomdata.Number(0, NumberMax)] = i
|
||||
}
|
||||
|
||||
log.Println(avl[12])
|
||||
}
|
||||
|
||||
func BenchmarkGodsHashmap(b *testing.B) {
|
||||
avl := hashmap.New()
|
||||
|
||||
b.N = CompartorSize * 10
|
||||
for i := 0; i < b.N; i++ {
|
||||
avl.Put(randomdata.Number(0, NumberMax), i)
|
||||
}
|
||||
|
||||
// b.ResetTimer()
|
||||
// b.StartTimer()
|
||||
// b.N = CompartorSize
|
||||
|
||||
// for i := 0; i < b.N; i++ {
|
||||
// avl[randomdata.Number(0, NumberMax)] = i
|
||||
// }
|
||||
}
|
||||
|
||||
func BenchmarkPut(b *testing.B) {
|
||||
avl := New(utils.IntComparator)
|
||||
|
||||
|
||||
103
avl/iterator.go
103
avl/iterator.go
@@ -24,26 +24,70 @@ func (iter *Iterator) Value() interface{} {
|
||||
return iter.cur.value
|
||||
}
|
||||
|
||||
func (iter *Iterator) Left() bool {
|
||||
if iter.cur.children[0] != nil {
|
||||
iter.dir = 0
|
||||
iter.cur = iter.cur.children[0]
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (iter *Iterator) Right() bool {
|
||||
if iter.cur.children[1] != nil {
|
||||
iter.dir = 0
|
||||
iter.cur = iter.cur.children[1]
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (iter *Iterator) Prev() (result bool) {
|
||||
|
||||
if iter.dir > -1 {
|
||||
if iter.dir == 1 && iter.cur != nil {
|
||||
iter.tstack.Clear()
|
||||
iter.curPushPrevStack(iter.cur)
|
||||
iter.up = iter.getPrevUp(iter.cur)
|
||||
}
|
||||
iter.dir = -1
|
||||
}
|
||||
|
||||
if iter.tstack.Size() == 0 {
|
||||
if iter.up == nil {
|
||||
return false
|
||||
}
|
||||
iter.tstack.Push(iter.up)
|
||||
iter.up = iter.getPrevUp(iter.up)
|
||||
}
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
iter.cur = v.(*Node)
|
||||
iter.curPushPrevStack(iter.cur)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (iter *Iterator) Next() (result bool) {
|
||||
|
||||
if iter.dir < 1 {
|
||||
if iter.dir == -1 {
|
||||
if iter.cur != nil {
|
||||
iter.tstack.Clear()
|
||||
iter.curPushNextStack(iter.cur)
|
||||
iter.up = iter.getNextUp(iter.cur)
|
||||
}
|
||||
if iter.dir < 1 { // 非 1(next 方向定义 -1 为 prev)
|
||||
if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈
|
||||
iter.tstack.Clear()
|
||||
iter.curPushNextStack(iter.cur) // 把当前cur计算的逆向回朔
|
||||
iter.up = iter.getNextUp(iter.cur) // cur 寻找下个要计算up
|
||||
}
|
||||
iter.dir = 1
|
||||
}
|
||||
|
||||
// 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值
|
||||
if iter.tstack.Size() == 0 {
|
||||
if iter.up != nil {
|
||||
iter.tstack.Push(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
} else {
|
||||
if iter.up == nil {
|
||||
return false
|
||||
}
|
||||
iter.tstack.Push(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
}
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
@@ -52,6 +96,7 @@ func (iter *Iterator) Next() (result bool) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 如果再次计算的栈为空, 则只能返回false
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -66,13 +111,13 @@ func (iter *Iterator) getNextUp(cur *Node) *Node {
|
||||
}
|
||||
|
||||
func (iter *Iterator) curPushNextStack(cur *Node) {
|
||||
next := cur.children[0]
|
||||
next := cur.children[0] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值
|
||||
|
||||
if next != nil {
|
||||
iter.tstack.Push(next)
|
||||
for next.children[1] != nil {
|
||||
next = next.children[1]
|
||||
iter.tstack.Push(next)
|
||||
iter.tstack.Push(next) // 入栈 用于回溯
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,35 +143,3 @@ func (iter *Iterator) curPushPrevStack(cur *Node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (iter *Iterator) Prev() (result bool) {
|
||||
|
||||
if iter.dir > -1 {
|
||||
|
||||
if iter.dir == 1 {
|
||||
if iter.cur != nil {
|
||||
iter.tstack.Clear()
|
||||
iter.curPushPrevStack(iter.cur)
|
||||
iter.up = iter.getPrevUp(iter.cur)
|
||||
}
|
||||
}
|
||||
iter.dir = -1
|
||||
}
|
||||
|
||||
if iter.tstack.Size() == 0 {
|
||||
if iter.up != nil {
|
||||
iter.tstack.Push(iter.up)
|
||||
iter.up = iter.getPrevUp(iter.up)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
iter.cur = v.(*Node)
|
||||
iter.curPushPrevStack(iter.cur)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user