getAround 完美完成
This commit is contained in:
@@ -186,7 +186,7 @@ func (avl *Tree) Values() []interface{} {
|
||||
return result
|
||||
}
|
||||
|
||||
func (avl *Tree) GetRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1
|
||||
func (avl *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1
|
||||
|
||||
if idx1^idx2 < 0 {
|
||||
if idx1 < 0 {
|
||||
@@ -244,16 +244,20 @@ func (avl *Tree) GetRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (avl *Tree) Get(key interface{}) (interface{}, bool) {
|
||||
n, ok := avl.GetNode(key)
|
||||
// func (avl *Tree) GetRange(v1, v2 interface{}) {
|
||||
// avl.getArountNode(v1)
|
||||
// }
|
||||
|
||||
func (avl *Tree) Get(value interface{}) (interface{}, bool) {
|
||||
n, ok := avl.GetNode(value)
|
||||
if ok {
|
||||
return n.value, true
|
||||
}
|
||||
return n, false
|
||||
}
|
||||
|
||||
func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) {
|
||||
an := avl.GetAroundNode(key)
|
||||
func (avl *Tree) GetAround(value interface{}) (result [3]interface{}) {
|
||||
an := avl.getArountNode(value)
|
||||
for i, n := range an {
|
||||
if n != nil {
|
||||
result[i] = n.value
|
||||
@@ -262,38 +266,174 @@ func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
func (avl *Tree) GetAroundNode(value interface{}) (result [3]*Node) {
|
||||
func (avl *Tree) getArountNode(value interface{}) (result [3]*Node) {
|
||||
var last *Node
|
||||
var lastc int
|
||||
|
||||
if cur, ok := avl.GetNode(value); ok {
|
||||
|
||||
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
|
||||
for n := avl.root; n != nil; {
|
||||
last = n
|
||||
c := avl.comparator(value, n.value)
|
||||
switch c {
|
||||
case -1:
|
||||
n = n.children[0]
|
||||
lastc = c
|
||||
case 1:
|
||||
n = n.children[1]
|
||||
lastc = c
|
||||
case 0:
|
||||
result[1] = n
|
||||
n = nil
|
||||
default:
|
||||
panic("Get comparator only is allowed in -1, 0, 1")
|
||||
}
|
||||
|
||||
iter = NewIterator(cur)
|
||||
iter.curPushNextStack(iter.up)
|
||||
iter.up = iter.getNextUp(iter.up)
|
||||
|
||||
if v, ok := iter.tstack.Pop(); ok {
|
||||
result[2] = v.(*Node)
|
||||
// iter.curPushNextStack(iter.cur)
|
||||
} else {
|
||||
result[2] = iter.up
|
||||
}
|
||||
|
||||
result[1] = cur
|
||||
}
|
||||
|
||||
switch lastc {
|
||||
case 1:
|
||||
const il = 0
|
||||
const ir = 1
|
||||
|
||||
if result[1] == nil {
|
||||
result[0] = last
|
||||
} else {
|
||||
l := result[1].children[il]
|
||||
r := result[1].children[ir]
|
||||
|
||||
if l == nil {
|
||||
result[0] = result[1].parent
|
||||
} else {
|
||||
for l.children[ir] != nil {
|
||||
l = l.children[ir]
|
||||
}
|
||||
result[0] = l
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
|
||||
parent := result[1].parent
|
||||
for ; parent != nil && parent.parent != nil; parent = parent.parent {
|
||||
child := getRelationship(parent)
|
||||
if child == (-lastc+2)/2 { // child 与 comparator 后左右的关系
|
||||
result[2] = parent.parent
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for r.children[il] != nil {
|
||||
r = r.children[il]
|
||||
}
|
||||
result[2] = r
|
||||
}
|
||||
}
|
||||
|
||||
case -1:
|
||||
|
||||
const il = 1
|
||||
const ir = 0
|
||||
|
||||
if result[1] == nil {
|
||||
result[2] = last
|
||||
} else {
|
||||
|
||||
l := result[1].children[il]
|
||||
r := result[1].children[ir]
|
||||
|
||||
if l == nil {
|
||||
result[2] = result[1].parent
|
||||
} else {
|
||||
for l.children[ir] != nil {
|
||||
l = l.children[ir]
|
||||
}
|
||||
result[2] = l
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
|
||||
parent := result[1].parent
|
||||
for ; parent != nil && parent.parent != nil; parent = parent.parent {
|
||||
child := getRelationship(parent)
|
||||
if child == (-lastc+2)/2 { // child 与 comparator 后左右的关系
|
||||
result[0] = parent.parent
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for r.children[il] != nil {
|
||||
r = r.children[il]
|
||||
}
|
||||
result[0] = r
|
||||
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
|
||||
const il = 0
|
||||
const ir = 1
|
||||
|
||||
if result[1] == nil {
|
||||
return
|
||||
}
|
||||
|
||||
l := result[1].children[il]
|
||||
r := result[1].children[ir]
|
||||
|
||||
if l == nil {
|
||||
result[0] = nil
|
||||
} else {
|
||||
for l.children[ir] != nil {
|
||||
l = l.children[ir]
|
||||
}
|
||||
result[0] = l
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
result[2] = nil
|
||||
} else {
|
||||
for r.children[il] != nil {
|
||||
r = r.children[il]
|
||||
}
|
||||
result[2] = r
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// func (avl *Tree) GetAroundNode(value interface{}) (result [3]*Node) {
|
||||
|
||||
// if cur, ok := avl.GetNode(value); ok {
|
||||
|
||||
// var iter *Iterator
|
||||
|
||||
// iter = NewIterator(cur)
|
||||
// iter.curPushPrevStack(iter.up)
|
||||
// iter.up = iter.getPrevUp(iter.up)
|
||||
|
||||
// if v, ok := iter.tstack.Pop(); ok {
|
||||
// result[2] = v.(*Node)
|
||||
// // iter.curPushPrevStack(iter.cur)
|
||||
// } else {
|
||||
// result[2] = iter.up
|
||||
// }
|
||||
|
||||
// iter = NewIterator(cur)
|
||||
// iter.curPushNextStack(iter.up)
|
||||
// iter.up = iter.getNextUp(iter.up)
|
||||
|
||||
// if v, ok := iter.tstack.Pop(); ok {
|
||||
// result[0] = v.(*Node)
|
||||
// // iter.curPushNextStack(iter.cur)
|
||||
// } else {
|
||||
// result[0] = iter.up
|
||||
// }
|
||||
|
||||
// result[1] = cur
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
func (avl *Tree) GetNode(value interface{}) (*Node, bool) {
|
||||
|
||||
for n := avl.root; n != nil; {
|
||||
@@ -338,7 +478,7 @@ func (avl *Tree) Put(value interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
if cur.size > 9 {
|
||||
if cur.size > 8 {
|
||||
ls, rs := cur.children[0].size, cur.children[1].size
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
@@ -773,9 +913,10 @@ func getSize(cur *Node) int {
|
||||
func (avl *Tree) fixRemoveHeight(cur *Node) {
|
||||
for cur != nil {
|
||||
cur.size--
|
||||
if cur.size > 9 {
|
||||
if cur.size > 8 {
|
||||
ls, rs := cur.children[0].size, cur.children[1].size
|
||||
if rs >= ls*2 || ls >= rs*2 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
avl.fixPutHeight(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestIterator(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestGetRange(t *testing.T) {
|
||||
func TestIndexRange(t *testing.T) {
|
||||
tree := New(utils.IntComparator)
|
||||
l := []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15}
|
||||
for _, v := range l {
|
||||
@@ -84,79 +84,121 @@ func TestGetRange(t *testing.T) {
|
||||
// t.Error(tree.Values(), tree.Size())
|
||||
|
||||
var result string
|
||||
result = spew.Sprint(tree.GetRange(0, 5))
|
||||
result = spew.Sprint(tree.IndexRange(0, 5))
|
||||
if result != "[3 7 14 14 14 15] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(2, 5))
|
||||
result = spew.Sprint(tree.IndexRange(2, 5))
|
||||
if result != "[14 14 14 15] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(10, 100))
|
||||
result = spew.Sprint(tree.IndexRange(10, 100))
|
||||
if result != "[30 40 40 40 40 50] false" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(15, 0)) // size = 16, index max = 15
|
||||
result = spew.Sprint(tree.IndexRange(15, 0)) // size = 16, index max = 15
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(16, 0)) // size = 16, index max = 15
|
||||
result = spew.Sprint(tree.IndexRange(16, 0)) // size = 16, index max = 15
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] false" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(5, 1)) // size = 16, index max = 15
|
||||
result = spew.Sprint(tree.IndexRange(5, 1)) // size = 16, index max = 15
|
||||
if result != "[15 14 14 14 7] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(-1, -5)) // size = 16, index max = 15
|
||||
result = spew.Sprint(tree.IndexRange(-1, -5)) // size = 16, index max = 15
|
||||
if result != "[50 40 40 40 40] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(-1, -16)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
result = spew.Sprint(tree.IndexRange(-1, -16)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(-1, -17)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
result = spew.Sprint(tree.IndexRange(-1, -17)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] false" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.GetRange(-5, -1)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
result = spew.Sprint(tree.IndexRange(-5, -1)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
if result != "[40 40 40 40 50] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAround(t *testing.T) {
|
||||
avl := New(utils.IntComparator)
|
||||
tree := 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)
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
var Result string
|
||||
|
||||
Result = spew.Sprint(avl.GetAround(3))
|
||||
if Result != "[7 3 <nil>]" {
|
||||
t.Error("avl.GetAround(3)) is error", Result)
|
||||
Result = spew.Sprint(tree.GetAround(17))
|
||||
if Result != "[16 17 20]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("17 is root, tree.GetAround(17)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(avl.GetAround(40))
|
||||
if Result != "[40 40 30]" {
|
||||
t.Error("avl.GetAround(40)) is error", Result)
|
||||
Result = spew.Sprint(tree.GetAround(3))
|
||||
if Result != "[<nil> 3 7]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("tree.GetAround(3)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(avl.GetAround(50))
|
||||
if Result != "[<nil> 50 40]" {
|
||||
t.Error("avl.GetAround(50)) is error", Result)
|
||||
Result = spew.Sprint(tree.GetAround(40))
|
||||
if Result != "[30 40 40]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("tree.GetAround(40)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(50))
|
||||
if Result != "[40 50 <nil>]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("tree.GetAround(50)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(18))
|
||||
if Result != "[<nil> <nil> 20]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("18 is not in list, tree.GetAround(18)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(5))
|
||||
if Result != "[3 <nil> <nil>]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("5 is not in list, tree.GetAround(5)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(2))
|
||||
if Result != "[<nil> <nil> 3]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("2 is not in list, tree.GetAround(2)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(100))
|
||||
if Result != "[50 <nil> <nil>]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("50 is not in list, tree.GetAround(50)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// // for test error case
|
||||
@@ -352,7 +394,7 @@ func BenchmarkGetRange(b *testing.B) {
|
||||
|
||||
for i := 0; i < execCount; i++ {
|
||||
for range l {
|
||||
tree.GetRange(i, i+49)
|
||||
tree.IndexRange(i, i+49)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,25 +580,56 @@ func BenchmarkPut(b *testing.B) {
|
||||
func TestPutStable(t *testing.T) {
|
||||
|
||||
// l := []int{14, 18, 20, 21, 22, 23, 19}
|
||||
var l []int
|
||||
for i := 0; len(l) < 10; i++ {
|
||||
l = append(l, randomdata.Number(0, 65))
|
||||
}
|
||||
for n := 0; n < 1000000; n++ {
|
||||
var l []int
|
||||
l = append(l, 60, 5, 15)
|
||||
for i := 0; len(l) < 11; i++ {
|
||||
l = append(l, randomdata.Number(3, 69))
|
||||
}
|
||||
|
||||
avl := New(utils.IntComparator)
|
||||
for _, v := range l {
|
||||
avl.Put(v)
|
||||
t.Error(avl.debugString(), v)
|
||||
}
|
||||
t.Error(avl.Values())
|
||||
for _, v := range []int{10, 0, 9, 5, -11, -10, -1, -5} {
|
||||
t.Error(avl.Index(v))
|
||||
}
|
||||
avl := New(utils.IntComparator)
|
||||
for _, v := range l {
|
||||
avl.Put(v)
|
||||
}
|
||||
result := avl.getArountNode(60)
|
||||
|
||||
avl.RemoveIndex(4)
|
||||
t.Error(avl.Index(4))
|
||||
t.Error(avl.Values())
|
||||
t.Error(avl.debugString())
|
||||
if result[2] == nil && avl.indexNode(-1) != result[1] {
|
||||
t.Error(avl.debugString())
|
||||
t.Error(avl.Values())
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = avl.getArountNode(5)
|
||||
if result[0] == nil && avl.indexNode(0) != result[1] {
|
||||
t.Error(avl.debugString())
|
||||
t.Error(avl.Values())
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = avl.getArountNode(2)
|
||||
if result[2] == nil && avl.indexNode(0) != result[2] {
|
||||
t.Error(avl.debugString())
|
||||
t.Error(avl.Values())
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = avl.getArountNode(70)
|
||||
if result[0] == nil && avl.indexNode(-1) != result[0] {
|
||||
t.Error(avl.debugString())
|
||||
t.Error(avl.Values())
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
}
|
||||
// for _, v := range []int{10, 0, 9, 5, -11, -10, -1, -5} {
|
||||
// t.Error(avl.Index(v))
|
||||
// // t.Error(avl.debugString())
|
||||
// }
|
||||
|
||||
// avl.RemoveIndex(4)
|
||||
// t.Error(avl.Index(4))
|
||||
// t.Error(avl.Values())
|
||||
// t.Error(avl.debugString())
|
||||
// t.Error(len(l), avl.debugString(), "\n", "-----------") // 3 6(4)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user