完美avl树
This commit is contained in:
parent
745f2ec3c3
commit
66145aa359
|
@ -47,7 +47,7 @@ func (avl *AVL) String() string {
|
||||||
if avl.size == 0 {
|
if avl.size == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
str := "AVL" + "\n"
|
str := "AVLTree" + "\n"
|
||||||
output(avl.root, "", true, &str)
|
output(avl.root, "", true, &str)
|
||||||
|
|
||||||
return str
|
return str
|
||||||
|
|
100
avl/avl_test.go
100
avl/avl_test.go
|
@ -48,10 +48,34 @@ func TestIterator(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Error(avl.TraversalDepth(1))
|
t.Error(avl.TraversalDepth(1))
|
||||||
iter := avl.Iterator()
|
iter := avl.Iterator()
|
||||||
|
|
||||||
|
for iter.Prev() {
|
||||||
|
t.Error(iter.Value())
|
||||||
|
}
|
||||||
|
t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value())
|
||||||
|
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
t.Error(iter.Value())
|
t.Error(iter.Value())
|
||||||
}
|
}
|
||||||
|
t.Error("next == false", iter.Value(), iter.Next(), iter.Value())
|
||||||
|
|
||||||
|
for iter.Prev() {
|
||||||
|
t.Error(iter.Value())
|
||||||
|
}
|
||||||
|
t.Error("prev == false", iter.Value())
|
||||||
|
|
||||||
|
for i := 0; iter.Next(); i++ {
|
||||||
|
t.Error(iter.Value())
|
||||||
|
if i >= 7 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
t.Error("next == false", iter.Value())
|
t.Error("next == false", iter.Value())
|
||||||
|
|
||||||
|
for iter.Prev() {
|
||||||
|
t.Error(iter.Value())
|
||||||
|
}
|
||||||
|
t.Error("prev == false", iter.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAround(t *testing.T) {
|
func TestGetAround(t *testing.T) {
|
||||||
|
@ -121,7 +145,9 @@ func TestPutComparatorRandom(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if avl.String() != godsavl.String() {
|
if avl.String() != godsavl.String() {
|
||||||
t.Error(content)
|
t.Error(godsavl.String())
|
||||||
|
t.Error(avl.String())
|
||||||
|
t.Error(content, n)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,6 +255,58 @@ ALL:
|
||||||
const PutCompartorSize = 300000
|
const PutCompartorSize = 300000
|
||||||
const NumberMax = 60000000
|
const NumberMax = 60000000
|
||||||
|
|
||||||
|
func BenchmarkIterator(b *testing.B) {
|
||||||
|
avl := New(utils.IntComparator)
|
||||||
|
b.N = PutCompartorSize
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
v := randomdata.Number(0, NumberMax)
|
||||||
|
avl.Put(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.StartTimer()
|
||||||
|
iter := avl.Iterator()
|
||||||
|
for iter.Next() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for iter.Prev() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for iter.Next() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGodsIterator(b *testing.B) {
|
||||||
|
avl := avltree.NewWithIntComparator()
|
||||||
|
b.N = PutCompartorSize
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
v := randomdata.Number(0, NumberMax)
|
||||||
|
avl.Put(v, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.StartTimer()
|
||||||
|
iter := avl.Iterator()
|
||||||
|
for iter.Next() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for iter.Prev() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for iter.Next() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkRemove(b *testing.B) {
|
func BenchmarkRemove(b *testing.B) {
|
||||||
|
|
||||||
avl := New(utils.IntComparator)
|
avl := New(utils.IntComparator)
|
||||||
|
@ -316,6 +394,12 @@ func BenchmarkGodsAvlGet(b *testing.B) {
|
||||||
func BenchmarkPut(b *testing.B) {
|
func BenchmarkPut(b *testing.B) {
|
||||||
avl := New(utils.IntComparator)
|
avl := New(utils.IntComparator)
|
||||||
|
|
||||||
|
for i := 0; i < 100000; i++ {
|
||||||
|
avl.Put(randomdata.Number(0, NumberMax))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.StartTimer()
|
||||||
b.N = PutCompartorSize
|
b.N = PutCompartorSize
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
avl.Put(randomdata.Number(0, NumberMax))
|
avl.Put(randomdata.Number(0, NumberMax))
|
||||||
|
@ -326,6 +410,13 @@ func BenchmarkPut(b *testing.B) {
|
||||||
func BenchmarkGodsRBPut(b *testing.B) {
|
func BenchmarkGodsRBPut(b *testing.B) {
|
||||||
rb := redblacktree.NewWithIntComparator()
|
rb := redblacktree.NewWithIntComparator()
|
||||||
|
|
||||||
|
for i := 0; i < 100000; i++ {
|
||||||
|
rb.Put(randomdata.Number(0, NumberMax), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
b.N = PutCompartorSize
|
b.N = PutCompartorSize
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
rb.Put(randomdata.Number(0, NumberMax), i)
|
rb.Put(randomdata.Number(0, NumberMax), i)
|
||||||
|
@ -336,6 +427,13 @@ func BenchmarkGodsRBPut(b *testing.B) {
|
||||||
func BenchmarkGodsPut(b *testing.B) {
|
func BenchmarkGodsPut(b *testing.B) {
|
||||||
avl := avltree.NewWithIntComparator()
|
avl := avltree.NewWithIntComparator()
|
||||||
|
|
||||||
|
for i := 0; i < 100000; i++ {
|
||||||
|
avl.Put(randomdata.Number(0, NumberMax), i)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
b.N = PutCompartorSize
|
b.N = PutCompartorSize
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
avl.Put(randomdata.Number(0, NumberMax), i)
|
avl.Put(randomdata.Number(0, NumberMax), i)
|
||||||
|
|
111
avl/iterator.go
111
avl/iterator.go
|
@ -1,24 +1,22 @@
|
||||||
package avl
|
package avl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/emirpasic/gods/stacks/arraystack"
|
"github.com/emirpasic/gods/stacks/arraystack"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Iterator struct {
|
type Iterator struct {
|
||||||
op *AVL
|
op *AVL
|
||||||
|
|
||||||
cur *Node
|
dir int
|
||||||
prevstack *arraystack.Stack
|
up *Node
|
||||||
nextstack *arraystack.Stack
|
cur *Node
|
||||||
|
tstack *arraystack.Stack
|
||||||
// curnext *Node
|
// curnext *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func initIterator(avltree *AVL) *Iterator {
|
func initIterator(avltree *AVL) *Iterator {
|
||||||
iter := &Iterator{op: avltree, prevstack: arraystack.New(), nextstack: arraystack.New()}
|
iter := &Iterator{op: avltree, tstack: arraystack.New()}
|
||||||
iter.cur = avltree.root
|
iter.up = avltree.root
|
||||||
// iter.nextstack.Push(avltree.root)
|
|
||||||
return iter
|
return iter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,14 +26,46 @@ func (iter *Iterator) Value() interface{} {
|
||||||
|
|
||||||
func (iter *Iterator) Next() (result bool) {
|
func (iter *Iterator) Next() (result bool) {
|
||||||
|
|
||||||
if iter.nextstack.Size() == 0 {
|
if iter.dir < 1 {
|
||||||
iter.nextstack.Push(iter.cur)
|
if iter.dir == -1 {
|
||||||
|
if iter.cur != nil {
|
||||||
|
iter.tstack.Clear()
|
||||||
|
iter.curPushNextStack(iter.cur)
|
||||||
|
|
||||||
|
iter.up = iter.cur
|
||||||
|
for iter.up != nil {
|
||||||
|
if iter.up.child == 1 {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iter.dir = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, ok := iter.nextstack.Pop(); ok {
|
if iter.tstack.Size() == 0 {
|
||||||
|
if iter.up != nil {
|
||||||
|
iter.tstack.Push(iter.up)
|
||||||
|
for iter.up != nil {
|
||||||
|
if iter.up.child == 1 {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := iter.tstack.Pop(); ok {
|
||||||
iter.cur = v.(*Node)
|
iter.cur = v.(*Node)
|
||||||
iter.curPushNextStack(iter.cur)
|
iter.curPushNextStack(iter.cur)
|
||||||
log.Println(iter.nextstack.Size())
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,19 +76,68 @@ func (iter *Iterator) curPushNextStack(cur *Node) {
|
||||||
next := cur.children[0]
|
next := cur.children[0]
|
||||||
|
|
||||||
if next != nil {
|
if next != nil {
|
||||||
iter.nextstack.Push(next)
|
iter.tstack.Push(next)
|
||||||
for next.children[1] != nil {
|
for next.children[1] != nil {
|
||||||
next = next.children[1]
|
next = next.children[1]
|
||||||
iter.nextstack.Push(next)
|
iter.tstack.Push(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) curPushPrevStack(cur *Node) {
|
||||||
|
prev := cur.children[1]
|
||||||
|
|
||||||
|
if prev != nil {
|
||||||
|
iter.tstack.Push(prev)
|
||||||
|
for prev.children[0] != nil {
|
||||||
|
prev = prev.children[0]
|
||||||
|
iter.tstack.Push(prev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iter *Iterator) Prev() (result bool) {
|
func (iter *Iterator) Prev() (result bool) {
|
||||||
|
|
||||||
if v, ok := iter.nextstack.Pop(); ok {
|
if iter.dir > -1 {
|
||||||
|
|
||||||
|
if iter.dir == 1 {
|
||||||
|
if iter.cur != nil {
|
||||||
|
iter.tstack.Clear()
|
||||||
|
iter.curPushPrevStack(iter.cur)
|
||||||
|
|
||||||
|
iter.up = iter.cur
|
||||||
|
for iter.up != nil {
|
||||||
|
if iter.up.child == 0 {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iter.dir = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if iter.tstack.Size() == 0 {
|
||||||
|
if iter.up != nil {
|
||||||
|
iter.tstack.Push(iter.up)
|
||||||
|
for iter.up != nil {
|
||||||
|
if iter.up.child == 0 {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
iter.up = iter.up.parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := iter.tstack.Pop(); ok {
|
||||||
iter.cur = v.(*Node)
|
iter.cur = v.(*Node)
|
||||||
iter.curPushNextStack(iter.cur)
|
iter.curPushPrevStack(iter.cur)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user