TODO: avlkey

This commit is contained in:
huangsimin
2019-03-13 19:09:24 +08:00
parent 226627f03e
commit b7e6045064
9 changed files with 1675 additions and 93 deletions

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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
}