TODO: GetRange
This commit is contained in:
parent
50e4bd754f
commit
06d55a2f9e
137
avl/avl.go
137
avl/avl.go
|
@ -120,6 +120,19 @@ func (avl *Tree) Remove(key interface{}) *Node {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Values 返回先序遍历的值
|
||||
func (avl *Tree) Values() []interface{} {
|
||||
mszie := 0
|
||||
if avl.root != nil {
|
||||
mszie = avl.size
|
||||
}
|
||||
result := make([]interface{}, 0, mszie)
|
||||
avl.Traversal(func(v interface{}) {
|
||||
result = append(result, v)
|
||||
}, DLR)
|
||||
return result
|
||||
}
|
||||
|
||||
func (avl *Tree) Get(key interface{}) (interface{}, bool) {
|
||||
n, ok := avl.GetNode(key)
|
||||
if ok {
|
||||
|
@ -143,57 +156,35 @@ func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) {
|
|||
}
|
||||
|
||||
func (avl *Tree) GetAroundNode(value interface{}) (result [3]*Node) {
|
||||
n := avl.root
|
||||
if cur, ok := avl.GetNode(value); ok {
|
||||
|
||||
for {
|
||||
var iter *Iterator
|
||||
|
||||
if n == nil {
|
||||
return
|
||||
iter = NewIterator(cur)
|
||||
iter.curPushPrevStack(iter.up)
|
||||
iter.up = iter.getPrevUp(iter.up)
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
result[0] = v.(*Node)
|
||||
// iter.curPushPrevStack(iter.cur)
|
||||
} else {
|
||||
result[0] = iter.up
|
||||
}
|
||||
|
||||
lastc := 0
|
||||
switch c := avl.comparator(value, n.value); c {
|
||||
case -1:
|
||||
if c != -lastc {
|
||||
result[0] = n
|
||||
}
|
||||
lastc = c
|
||||
n = n.children[0]
|
||||
case 1:
|
||||
if c != -lastc {
|
||||
result[2] = n
|
||||
}
|
||||
lastc = c
|
||||
n = n.children[1]
|
||||
case 0:
|
||||
iter = NewIterator(cur)
|
||||
iter.curPushNextStack(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
|
||||
switch lastc {
|
||||
case -1:
|
||||
if n.children[1] != nil {
|
||||
result[0] = n.children[1]
|
||||
}
|
||||
case 1:
|
||||
if n.children[0] != nil {
|
||||
result[2] = n.children[0]
|
||||
}
|
||||
case 0:
|
||||
|
||||
if n.children[1] != nil {
|
||||
result[0] = n.children[1]
|
||||
}
|
||||
if n.children[0] != nil {
|
||||
result[2] = n.children[0]
|
||||
}
|
||||
|
||||
result[1] = n
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
panic("Get comparator only is allowed in -1, 0, 1")
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
result[2] = v.(*Node)
|
||||
// iter.curPushNextStack(iter.cur)
|
||||
} else {
|
||||
result[2] = iter.up
|
||||
}
|
||||
|
||||
result[1] = cur
|
||||
}
|
||||
return
|
||||
}
|
||||
func (avl *Tree) GetNode(value interface{}) (*Node, bool) {
|
||||
|
||||
|
@ -251,47 +242,64 @@ func (avl *Tree) debugString() string {
|
|||
return str
|
||||
}
|
||||
|
||||
func (avl *Tree) TraversalBreadth() (result []interface{}) {
|
||||
result = make([]interface{}, 0, avl.size)
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
result = append(result, cur.value)
|
||||
traverasl(cur.children[0])
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
return
|
||||
}
|
||||
type TraversalMethod int
|
||||
|
||||
func (avl *Tree) TraversalDepth(leftright int) (result []interface{}) {
|
||||
result = make([]interface{}, 0, avl.size)
|
||||
if leftright < 0 {
|
||||
const (
|
||||
_ TraversalMethod = iota
|
||||
//DLR 前序遍历
|
||||
DLR
|
||||
//LDR 中序遍历
|
||||
LDR
|
||||
//LRD 后序遍历
|
||||
LRD
|
||||
)
|
||||
|
||||
// Traversal 遍历的方法
|
||||
func (avl *Tree) Traversal(every func(v interface{}), traversalMethod ...interface{}) {
|
||||
if avl.root == nil {
|
||||
return
|
||||
}
|
||||
|
||||
method := LDR
|
||||
if len(traversalMethod) != 0 {
|
||||
method = traversalMethod[0].(TraversalMethod)
|
||||
}
|
||||
|
||||
switch method {
|
||||
case DLR:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
traverasl(cur.children[0])
|
||||
result = append(result, cur.value)
|
||||
every(cur.value)
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
} else {
|
||||
case LRD:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
traverasl(cur.children[1])
|
||||
result = append(result, cur.value)
|
||||
every(cur.value)
|
||||
traverasl(cur.children[0])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
case LDR:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
every(cur.value)
|
||||
traverasl(cur.children[0])
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -564,7 +572,6 @@ func abs(n int) int {
|
|||
}
|
||||
|
||||
func (avl *Tree) fixRemoveHeight(cur *Node) {
|
||||
|
||||
for {
|
||||
|
||||
lefth, rigthh, lrmax := getMaxAndChildrenHeight(cur)
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/emirpasic/gods/utils"
|
||||
)
|
||||
|
||||
const CompartorSize = 1000000
|
||||
const CompartorSize = 100
|
||||
const NumberMax = 600
|
||||
|
||||
func TestSave(t *testing.T) {
|
||||
|
@ -124,7 +124,7 @@ func TestGetAround(t *testing.T) {
|
|||
}
|
||||
|
||||
if spew.Sprint(avl.GetAround(40)) != "[40 40 30]" {
|
||||
t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50)))
|
||||
t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(40)))
|
||||
}
|
||||
|
||||
if spew.Sprint(avl.GetAround(50)) != "[<nil> 50 40]" {
|
||||
|
@ -241,7 +241,7 @@ ALL:
|
|||
for i := 0; i < 100; i++ {
|
||||
avl.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
s1 := spew.Sprint(avl.TraversalDepth(-1))
|
||||
s1 := spew.Sprint(avl.Values())
|
||||
s2 := spew.Sprint(gods.Values())
|
||||
if s1 != s2 {
|
||||
t.Error("avl remove error", "avlsize = ", avl.Size())
|
||||
|
@ -251,6 +251,7 @@ ALL:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
|
@ -279,7 +280,7 @@ ALL:
|
|||
for i := 0; i < 10; i++ {
|
||||
avl.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
if spew.Sprint(gods.Values()) != spew.Sprint(avl.TraversalDepth(-1)) && avl.size != 0 {
|
||||
if spew.Sprint(gods.Values()) != spew.Sprint(avl.Values()) && avl.size != 0 {
|
||||
// if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 {
|
||||
t.Error(src1)
|
||||
t.Error(src2)
|
||||
|
@ -316,27 +317,6 @@ func BenchmarkIterator(b *testing.B) {
|
|||
|
||||
}
|
||||
|
||||
func BenchmarkGodsIterator(b *testing.B) {
|
||||
tree := avltree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
|
||||
for _, v := range l {
|
||||
tree.Put(v, v)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
iter := tree.Iterator()
|
||||
for iter.Next() {
|
||||
}
|
||||
for iter.Prev() {
|
||||
}
|
||||
for iter.Next() {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRemove(b *testing.B) {
|
||||
tree := New(utils.IntComparator)
|
||||
|
||||
|
|
|
@ -20,8 +20,10 @@ func initIterator(avltree *Tree) *Iterator {
|
|||
return iter
|
||||
}
|
||||
|
||||
func NewIterator(tree *Tree) *Iterator {
|
||||
return initIterator(tree)
|
||||
func NewIterator(n *Node) *Iterator {
|
||||
iter := &Iterator{tstack: lastack.New()}
|
||||
iter.up = n
|
||||
return iter
|
||||
}
|
||||
|
||||
func (iter *Iterator) Value() interface{} {
|
||||
|
|
|
@ -36,8 +36,10 @@ func New(comparator utils.Comparator) *Tree {
|
|||
|
||||
func (avl *Tree) String() string {
|
||||
str := "AVLTree\n"
|
||||
if avl.root == nil {
|
||||
return str + "nil"
|
||||
}
|
||||
output(avl.root, "", true, &str)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
|
@ -55,7 +57,7 @@ func (avl *Tree) Size() int {
|
|||
func (avl *Tree) Remove(key interface{}) *Node {
|
||||
|
||||
if n, ok := avl.GetNode(key); ok {
|
||||
if avl.root == n {
|
||||
if avl.root.size == 1 {
|
||||
avl.root = nil
|
||||
return n
|
||||
}
|
||||
|
@ -112,6 +114,19 @@ func (avl *Tree) Remove(key interface{}) *Node {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Values 返回先序遍历的值
|
||||
func (avl *Tree) Values() []interface{} {
|
||||
mszie := 0
|
||||
if avl.root != nil {
|
||||
mszie = avl.root.size
|
||||
}
|
||||
result := make([]interface{}, 0, mszie)
|
||||
avl.Traversal(func(v interface{}) {
|
||||
result = append(result, v)
|
||||
}, LDR)
|
||||
return result
|
||||
}
|
||||
|
||||
func (avl *Tree) Get(key interface{}) (interface{}, bool) {
|
||||
n, ok := avl.GetNode(key)
|
||||
if ok {
|
||||
|
@ -121,6 +136,35 @@ func (avl *Tree) Get(key interface{}) (interface{}, bool) {
|
|||
}
|
||||
|
||||
func (avl *Tree) GetRange(min, max interface{}) []interface{} {
|
||||
|
||||
var minN *Node
|
||||
for minN = avl.root; minN != nil; {
|
||||
switch c := avl.comparator(min, minN.value); c {
|
||||
case -1:
|
||||
minN = minN.children[0]
|
||||
case 1:
|
||||
minN = minN.children[1]
|
||||
case 0:
|
||||
break
|
||||
default:
|
||||
panic("Get comparator only is allowed in -1, 0, 1")
|
||||
}
|
||||
}
|
||||
|
||||
var maxN *Node
|
||||
for maxN = avl.root; maxN != nil; {
|
||||
switch c := avl.comparator(min, maxN.value); c {
|
||||
case -1:
|
||||
maxN = maxN.children[0]
|
||||
case 1:
|
||||
maxN = maxN.children[1]
|
||||
case 0:
|
||||
break
|
||||
default:
|
||||
panic("Get comparator only is allowed in -1, 0, 1")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -135,57 +179,36 @@ func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) {
|
|||
}
|
||||
|
||||
func (avl *Tree) GetAroundNode(value interface{}) (result [3]*Node) {
|
||||
n := avl.root
|
||||
|
||||
for {
|
||||
if cur, ok := avl.GetNode(value); ok {
|
||||
|
||||
if n == nil {
|
||||
return
|
||||
var iter *Iterator
|
||||
|
||||
iter = NewIterator(cur)
|
||||
iter.curPushPrevStack(iter.up)
|
||||
iter.up = iter.getPrevUp(iter.up)
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
result[0] = v.(*Node)
|
||||
// iter.curPushPrevStack(iter.cur)
|
||||
} else {
|
||||
result[0] = iter.up
|
||||
}
|
||||
|
||||
lastc := 0
|
||||
switch c := avl.comparator(value, n.value); c {
|
||||
case -1:
|
||||
if c != -lastc {
|
||||
result[0] = n
|
||||
}
|
||||
lastc = c
|
||||
n = n.children[0]
|
||||
case 1:
|
||||
if c != -lastc {
|
||||
result[2] = n
|
||||
}
|
||||
lastc = c
|
||||
n = n.children[1]
|
||||
case 0:
|
||||
iter = NewIterator(cur)
|
||||
iter.curPushNextStack(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
|
||||
switch lastc {
|
||||
case -1:
|
||||
if n.children[1] != nil {
|
||||
result[0] = n.children[1]
|
||||
}
|
||||
case 1:
|
||||
if n.children[0] != nil {
|
||||
result[2] = n.children[0]
|
||||
}
|
||||
case 0:
|
||||
|
||||
if n.children[1] != nil {
|
||||
result[0] = n.children[1]
|
||||
}
|
||||
if n.children[0] != nil {
|
||||
result[2] = n.children[0]
|
||||
}
|
||||
|
||||
result[1] = n
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
panic("Get comparator only is allowed in -1, 0, 1")
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
result[2] = v.(*Node)
|
||||
// iter.curPushNextStack(iter.cur)
|
||||
} else {
|
||||
result[2] = iter.up
|
||||
}
|
||||
|
||||
result[1] = cur
|
||||
}
|
||||
return
|
||||
}
|
||||
func (avl *Tree) GetNode(value interface{}) (*Node, bool) {
|
||||
|
||||
|
@ -246,61 +269,107 @@ func (avl *Tree) Put(value interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
func (avl *Tree) debugString() string {
|
||||
str := "AVLTree\n"
|
||||
outputfordebug(avl.root, "", true, &str)
|
||||
return str
|
||||
}
|
||||
type TraversalMethod int
|
||||
|
||||
func (avl *Tree) TraversalBreadth() (result []interface{}) {
|
||||
const (
|
||||
// L = left R = right D = Value(dest)
|
||||
_ TraversalMethod = iota
|
||||
//DLR 先值 然后左递归 右递归 下面同理
|
||||
DLR
|
||||
//LDR 先从左边有序访问到右边 从小到大
|
||||
LDR
|
||||
// LRD 同理
|
||||
LRD
|
||||
|
||||
// DRL 同理
|
||||
DRL
|
||||
|
||||
// RDL 先从右边有序访问到左边 从大到小
|
||||
RDL
|
||||
|
||||
// RLD 同理
|
||||
RLD
|
||||
)
|
||||
|
||||
// Traversal 遍历的方法
|
||||
func (avl *Tree) Traversal(every func(v interface{}), traversalMethod ...interface{}) {
|
||||
if avl.root == nil {
|
||||
return
|
||||
}
|
||||
|
||||
result = make([]interface{}, 0, avl.root.size)
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
method := DLR
|
||||
if len(traversalMethod) != 0 {
|
||||
method = traversalMethod[0].(TraversalMethod)
|
||||
}
|
||||
|
||||
switch method {
|
||||
case DLR:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
every(cur.value)
|
||||
traverasl(cur.children[0])
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
result = append(result, cur.value)
|
||||
traverasl(cur.children[0])
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
return
|
||||
}
|
||||
|
||||
func (avl *Tree) TraversalDepth(leftright int) (result []interface{}) {
|
||||
if avl.root == nil {
|
||||
return
|
||||
}
|
||||
|
||||
result = make([]interface{}, 0, avl.root.size)
|
||||
if leftright < 0 {
|
||||
traverasl(avl.root)
|
||||
case LDR:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
traverasl(cur.children[0])
|
||||
result = append(result, cur.value)
|
||||
every(cur.value)
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
} else {
|
||||
case LRD:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
traverasl(cur.children[0])
|
||||
traverasl(cur.children[1])
|
||||
every(cur.value)
|
||||
}
|
||||
traverasl(avl.root)
|
||||
case DRL:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
every(cur.value)
|
||||
traverasl(cur.children[0])
|
||||
traverasl(cur.children[1])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
case RDL:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
traverasl(cur.children[1])
|
||||
result = append(result, cur.value)
|
||||
every(cur.value)
|
||||
traverasl(cur.children[0])
|
||||
}
|
||||
traverasl(avl.root)
|
||||
case RLD:
|
||||
var traverasl func(cur *Node)
|
||||
traverasl = func(cur *Node) {
|
||||
if cur == nil {
|
||||
return
|
||||
}
|
||||
traverasl(cur.children[1])
|
||||
traverasl(cur.children[0])
|
||||
every(cur.value)
|
||||
}
|
||||
traverasl(avl.root)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -503,11 +572,6 @@ func (avl *Tree) fixRemoveHeight(cur *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
// func abs(n int) int {
|
||||
// y := n >> 31
|
||||
// return (n ^ y) - y
|
||||
// }
|
||||
|
||||
func (avl *Tree) fixPutHeight(cur *Node, lefts, rigths int) {
|
||||
if lefts > rigths {
|
||||
l := cur.children[0]
|
||||
|
@ -598,3 +662,12 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) {
|
|||
outputfordebug(node.children[0], newPrefix, true, str)
|
||||
}
|
||||
}
|
||||
|
||||
func (avl *Tree) debugString() string {
|
||||
str := "AVLTree\n"
|
||||
if avl.root == nil {
|
||||
return str + "nil"
|
||||
}
|
||||
outputfordebug(avl.root, "", true, &str)
|
||||
return str
|
||||
}
|
||||
|
|
|
@ -62,109 +62,70 @@ func loadTestData() []int {
|
|||
return l
|
||||
}
|
||||
|
||||
// func TestIterator(t *testing.T) {
|
||||
// avl := New(utils.IntComparator)
|
||||
// for _, v := range []int{1, 2, 7, 4, 5, 6, 7, 14, 15, 20, 30, 21, 3} {
|
||||
// // t.Error(v)
|
||||
// avl.Put(v)
|
||||
func TestIterator(t *testing.T) {
|
||||
avl := New(utils.IntComparator)
|
||||
for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 40, 50, 3, 40, 40, 40, 15} {
|
||||
avl.Put(v)
|
||||
}
|
||||
t.Error(avl.Values())
|
||||
t.Error(avl.debugString())
|
||||
}
|
||||
|
||||
// }
|
||||
// // ` AVLTree
|
||||
// // │ ┌── 30
|
||||
// // │ │ └── 21
|
||||
// // │ ┌── 20
|
||||
// // │ │ └── 15
|
||||
// // └── 14
|
||||
// // │ ┌── 7
|
||||
// // │ ┌── 7
|
||||
// // │ │ └── 6
|
||||
// // └── 5
|
||||
// // │ ┌── 4
|
||||
// // │ │ └── 3
|
||||
// // └── 2
|
||||
// // └── 1`
|
||||
func TestGetAround(t *testing.T) {
|
||||
avl := New(utils.IntComparator)
|
||||
for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} {
|
||||
avl.Put(v)
|
||||
}
|
||||
|
||||
// iter := avl.Iterator() // root start point
|
||||
var Result string
|
||||
|
||||
// l := []int{14, 15, 20, 21, 30}
|
||||
Result = spew.Sprint(avl.GetAround(3))
|
||||
if Result != "[7 3 <nil>]" {
|
||||
t.Error("avl.GetAround(3)) is error", Result)
|
||||
}
|
||||
|
||||
// for i := 0; iter.Prev(); i++ {
|
||||
// if iter.Value().(int) != l[i] {
|
||||
// t.Error("iter prev error", iter.Value(), l[i])
|
||||
// }
|
||||
// }
|
||||
Result = spew.Sprint(avl.GetAround(40))
|
||||
if Result != "[40 40 30]" {
|
||||
t.Error("avl.GetAround(40)) is error", Result)
|
||||
}
|
||||
|
||||
// iter.Prev()
|
||||
// if iter.Value().(int) != 30 {
|
||||
// t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value())
|
||||
// }
|
||||
|
||||
// l = []int{21, 20, 15, 14, 7, 7, 6, 5, 4, 3, 2, 1}
|
||||
// for i := 0; iter.Next(); i++ { // cur is 30 next is 21
|
||||
// if iter.Value().(int) != l[i] {
|
||||
// t.Error(iter.Value())
|
||||
// }
|
||||
// }
|
||||
|
||||
// if iter.Next() != false {
|
||||
// t.Error("Next is error, cur is tail, val = 1 Next return false")
|
||||
// }
|
||||
// if iter.Value().(int) != 1 { // cur is 1
|
||||
// t.Error("next == false", iter.Value(), iter.Next(), iter.Value())
|
||||
// }
|
||||
|
||||
// if iter.Prev() != true && iter.Value().(int) != 2 {
|
||||
// t.Error("next to prev is error")
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestGetAround(t *testing.T) {
|
||||
// avl := New(utils.IntComparator)
|
||||
// for _, v := range []int{7, 14, 15, 20, 30, 21, 40, 40, 50, 3, 40, 40, 40} {
|
||||
// avl.Put(v)
|
||||
// }
|
||||
|
||||
// if spew.Sprint(avl.GetAround(30)) != "[40 30 21]" {
|
||||
// t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(30)))
|
||||
// }
|
||||
|
||||
// if spew.Sprint(avl.GetAround(40)) != "[40 40 30]" {
|
||||
// t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50)))
|
||||
// }
|
||||
|
||||
// if spew.Sprint(avl.GetAround(50)) != "[<nil> 50 40]" {
|
||||
// t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50)))
|
||||
// }
|
||||
// }
|
||||
Result = spew.Sprint(avl.GetAround(50))
|
||||
if Result != "[<nil> 50 40]" {
|
||||
t.Error("avl.GetAround(50)) is error", Result)
|
||||
}
|
||||
}
|
||||
|
||||
// // for test error case
|
||||
|
||||
// func TestPutComparatorRandom(t *testing.T) {
|
||||
func TestPutComparatorRandom(t *testing.T) {
|
||||
|
||||
// for n := 0; n < 300000; n++ {
|
||||
// avl := New(utils.IntComparator)
|
||||
// godsavl := avltree.NewWithIntComparator()
|
||||
for n := 0; n < 300000; n++ {
|
||||
avl := New(utils.IntComparator)
|
||||
godsavl := avltree.NewWithIntComparator()
|
||||
|
||||
// content := ""
|
||||
// m := make(map[int]int)
|
||||
// for i := 0; len(m) < 10; i++ {
|
||||
// v := randomdata.Number(0, 65535)
|
||||
// if _, ok := m[v]; !ok {
|
||||
// m[v] = v
|
||||
// content += spew.Sprint(v) + ","
|
||||
// avl.Put(v)
|
||||
// godsavl.Put(v, v)
|
||||
// }
|
||||
// }
|
||||
content := ""
|
||||
m := make(map[int]int)
|
||||
for i := 0; len(m) < 10; i++ {
|
||||
v := randomdata.Number(0, 65535)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
content += spew.Sprint(v) + ","
|
||||
avl.Put(v)
|
||||
godsavl.Put(v, v)
|
||||
}
|
||||
}
|
||||
|
||||
// if avl.String() != godsavl.String() {
|
||||
// t.Error(godsavl.String())
|
||||
// t.Error(avl.debugString())
|
||||
// t.Error(content, n)
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
s1 := spew.Sprint(avl.Values())
|
||||
s2 := spew.Sprint(godsavl.Values())
|
||||
|
||||
if s1 != s2 {
|
||||
t.Error(godsavl.String())
|
||||
t.Error(avl.debugString())
|
||||
t.Error(content, n)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
avl := New(utils.IntComparator)
|
||||
|
@ -186,7 +147,6 @@ func TestGet(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
|
||||
ALL:
|
||||
for c := 0; c < 5000; c++ {
|
||||
avl := New(utils.IntComparator)
|
||||
|
@ -194,7 +154,7 @@ ALL:
|
|||
var l []int
|
||||
m := make(map[int]int)
|
||||
|
||||
for i := 0; len(l) < 100; i++ {
|
||||
for i := 0; len(l) < 10; i++ {
|
||||
v := randomdata.Number(0, 100000)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
|
@ -204,13 +164,16 @@ ALL:
|
|||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
for i := 0; i < 10; i++ {
|
||||
|
||||
avl.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
s1 := spew.Sprint(avl.TraversalDepth(-1))
|
||||
|
||||
s1 := spew.Sprint(avl.Values())
|
||||
s2 := spew.Sprint(gods.Values())
|
||||
if s1 != s2 {
|
||||
t.Error("avl remove error", "avlsize = ", avl.Size())
|
||||
t.Error(avl.root, i, l[i])
|
||||
t.Error(s1)
|
||||
t.Error(s2)
|
||||
break ALL
|
||||
|
@ -245,7 +208,7 @@ ALL:
|
|||
for i := 0; i < 10; i++ {
|
||||
avl.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
if avl.root != nil && spew.Sprint(gods.Values()) != spew.Sprint(avl.TraversalDepth(-1)) {
|
||||
if avl.root != nil && spew.Sprint(gods.Values()) != spew.Sprint(avl.Values()) {
|
||||
// if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 {
|
||||
t.Error(src1)
|
||||
t.Error(src2)
|
||||
|
@ -260,48 +223,26 @@ ALL:
|
|||
}
|
||||
}
|
||||
|
||||
// func BenchmarkIterator(b *testing.B) {
|
||||
// tree := New(utils.IntComparator)
|
||||
func BenchmarkIterator(b *testing.B) {
|
||||
tree := New(utils.IntComparator)
|
||||
|
||||
// l := loadTestData()
|
||||
// b.N = len(l)
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
|
||||
// for _, v := range l {
|
||||
// tree.Put(v)
|
||||
// }
|
||||
for _, v := range l {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
// b.ResetTimer()
|
||||
// b.StartTimer()
|
||||
// iter := tree.Iterator()
|
||||
// for iter.Next() {
|
||||
// }
|
||||
// for iter.Prev() {
|
||||
// }
|
||||
// for iter.Next() {
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// func BenchmarkGodsIterator(b *testing.B) {
|
||||
// tree := avltree.NewWithIntComparator()
|
||||
|
||||
// l := loadTestData()
|
||||
// b.N = len(l)
|
||||
|
||||
// for _, v := range l {
|
||||
// tree.Put(v, v)
|
||||
// }
|
||||
|
||||
// b.ResetTimer()
|
||||
// b.StartTimer()
|
||||
// iter := tree.Iterator()
|
||||
// for iter.Next() {
|
||||
// }
|
||||
// for iter.Prev() {
|
||||
// }
|
||||
// for iter.Next() {
|
||||
// }
|
||||
// }
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
iter := tree.Iterator()
|
||||
for iter.Next() {
|
||||
}
|
||||
for iter.Prev() {
|
||||
}
|
||||
for iter.Next() {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRemove(b *testing.B) {
|
||||
tree := New(utils.IntComparator)
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
)
|
||||
|
||||
type Iterator struct {
|
||||
op *Tree
|
||||
|
||||
dir int
|
||||
up *Node
|
||||
cur *Node
|
||||
|
@ -15,13 +13,15 @@ type Iterator struct {
|
|||
}
|
||||
|
||||
func initIterator(avltree *Tree) *Iterator {
|
||||
iter := &Iterator{op: avltree, tstack: lastack.New()}
|
||||
iter := &Iterator{tstack: lastack.New()}
|
||||
iter.up = avltree.root
|
||||
return iter
|
||||
}
|
||||
|
||||
func NewIterator(tree *Tree) *Iterator {
|
||||
return initIterator(tree)
|
||||
func NewIterator(n *Node) *Iterator {
|
||||
iter := &Iterator{tstack: lastack.New()}
|
||||
iter.up = n
|
||||
return iter
|
||||
}
|
||||
|
||||
func (iter *Iterator) Value() interface{} {
|
||||
|
@ -46,6 +46,36 @@ func (iter *Iterator) Right() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func GetPrev(cur *Node, idx int) *Node {
|
||||
|
||||
iter := NewIterator(cur)
|
||||
iter.curPushPrevStack(iter.up)
|
||||
iter.up = iter.getPrevUp(iter.up)
|
||||
|
||||
for i := 0; i < idx; i++ {
|
||||
|
||||
if iter.tstack.Size() == 0 {
|
||||
if iter.up == nil {
|
||||
return nil
|
||||
}
|
||||
iter.tstack.Push(iter.up)
|
||||
iter.up = iter.getPrevUp(iter.up)
|
||||
}
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
iter.cur = v.(*Node)
|
||||
if i == idx-1 {
|
||||
return iter.cur
|
||||
}
|
||||
iter.curPushPrevStack(iter.cur)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return cur
|
||||
}
|
||||
|
||||
func (iter *Iterator) Prev() (result bool) {
|
||||
|
||||
if iter.dir > -1 {
|
||||
|
@ -73,6 +103,35 @@ func (iter *Iterator) Prev() (result bool) {
|
|||
|
||||
return false
|
||||
}
|
||||
func GetNext(cur *Node, idx int) *Node {
|
||||
|
||||
iter := NewIterator(cur)
|
||||
iter.curPushNextStack(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
|
||||
for i := 0; i < idx; i++ {
|
||||
|
||||
if iter.tstack.Size() == 0 {
|
||||
if iter.up == nil {
|
||||
return nil
|
||||
}
|
||||
iter.tstack.Push(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
}
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
iter.cur = v.(*Node)
|
||||
if i == idx-1 {
|
||||
return iter.cur
|
||||
}
|
||||
iter.curPushNextStack(iter.cur)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return cur
|
||||
}
|
||||
|
||||
func (iter *Iterator) Next() (result bool) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user