From 47fea0ca3bb93593c6b8cffbddec6a5c7fff65bc Mon Sep 17 00:00:00 2001 From: huangsimin Date: Fri, 22 Mar 2019 18:00:21 +0800 Subject: [PATCH] =?UTF-8?q?Range=20=E6=B5=8B=E9=80=9A=E5=B9=B6=E4=B8=94=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20getAround=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- avl/avl_test.go | 2 +- avlindex/avlindex.go | 350 +++++++++++++++++++++++--------------- avlindex/avlindex_test.go | 73 +++++++- 3 files changed, 277 insertions(+), 148 deletions(-) diff --git a/avl/avl_test.go b/avl/avl_test.go index b6970bc..94c5443 100644 --- a/avl/avl_test.go +++ b/avl/avl_test.go @@ -19,7 +19,7 @@ import ( const CompartorSize = 100 const NumberMax = 600 -func TestSave(t *testing.T) { +func Save(t *testing.T) { f, err := os.OpenFile("../l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { diff --git a/avlindex/avlindex.go b/avlindex/avlindex.go index 7f3cbe7..33824a3 100644 --- a/avlindex/avlindex.go +++ b/avlindex/avlindex.go @@ -36,28 +36,28 @@ func New(comparator utils.Comparator) *Tree { return &Tree{comparator: comparator} } -func (avl *Tree) String() string { +func (tree *Tree) String() string { str := "AVLTree\n" - if avl.root == nil { + if tree.root == nil { return str + "nil" } - output(avl.root, "", true, &str) + output(tree.root, "", true, &str) return str } -func (avl *Tree) Iterator() *Iterator { - return initIterator(avl) +func (tree *Tree) Iterator() *Iterator { + return initIterator(tree) } -func (avl *Tree) Size() int { - if avl.root == nil { +func (tree *Tree) Size() int { + if tree.root == nil { return 0 } - return avl.root.size + return tree.root.size } -func (avl *Tree) indexNode(idx int) *Node { - cur := avl.root +func (tree *Tree) indexNode(idx int) *Node { + cur := tree.root if idx >= 0 { for cur != nil { ls := getSize(cur.children[0]) @@ -87,26 +87,84 @@ func (avl *Tree) indexNode(idx int) *Node { return nil } -func (avl *Tree) Index(idx int) (interface{}, bool) { - n := avl.indexNode(idx) +func (tree *Tree) Index(idx int) (interface{}, bool) { + n := tree.indexNode(idx) if n != nil { return n.value, true } return nil, false } -func (avl *Tree) RemoveIndex(idx int) bool { - n := avl.indexNode(idx) +func (tree *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1 + + if idx1^idx2 < 0 { + if idx1 < 0 { + idx1 = tree.root.size + idx1 - 1 + } else { + idx2 = tree.root.size + idx2 - 1 + } + } + + if idx1 > idx2 { + ok = true + if idx1 >= tree.root.size { + idx1 = tree.root.size - 1 + ok = false + } + + n := tree.indexNode(idx1) + iter := NewIterator(n) + result = make([]interface{}, 0, idx1-idx2) + for i := idx2; i <= idx1; i++ { + if iter.Next() { + result = append(result, iter.Value()) + } else { + ok = false + return + } + } + + return + + } else { + ok = true + if idx2 >= tree.root.size { + idx2 = tree.root.size - 1 + ok = false + } + + if n := tree.indexNode(idx1); n != nil { + iter := NewIterator(n) + result = make([]interface{}, 0, idx2-idx1) + for i := idx1; i <= idx2; i++ { + if iter.Prev() { + result = append(result, iter.Value()) + } else { + ok = false + return + } + } + + return + } + + } + + return nil, false +} + +func (tree *Tree) RemoveIndex(idx int) bool { + n := tree.indexNode(idx) if n != nil { - avl.removeNode(n) + tree.removeNode(n) return true } return false } -func (avl *Tree) removeNode(n *Node) { - if avl.root.size == 1 { - avl.root = nil +func (tree *Tree) removeNode(n *Node) { + if tree.root.size == 1 { + tree.root = nil // return n return } @@ -115,7 +173,7 @@ func (avl *Tree) removeNode(n *Node) { if ls == 0 && rs == 0 { p := n.parent p.children[getRelationship(n)] = nil - avl.fixSizeWithRemove(p) + tree.fixSizeWithRemove(p) // return n return } @@ -153,19 +211,19 @@ func (avl *Tree) removeNode(n *Node) { // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 if cparent == n { - avl.fixSizeWithRemove(n) + tree.fixSizeWithRemove(n) } else { - avl.fixSizeWithRemove(cparent) + tree.fixSizeWithRemove(cparent) } // return cur return } -func (avl *Tree) Remove(key interface{}) bool { +func (tree *Tree) Remove(key interface{}) bool { - if n, ok := avl.GetNode(key); ok { - avl.removeNode(n) + if n, ok := tree.GetNode(key); ok { + tree.removeNode(n) return true } // return nil @@ -173,99 +231,93 @@ func (avl *Tree) Remove(key interface{}) bool { } // Values 返回先序遍历的值 -func (avl *Tree) Values() []interface{} { +func (tree *Tree) Values() []interface{} { mszie := 0 - if avl.root != nil { - mszie = avl.root.size + if tree.root != nil { + mszie = tree.root.size } result := make([]interface{}, 0, mszie) - avl.Traversal(func(v interface{}) bool { + tree.Traversal(func(v interface{}) bool { result = append(result, v) return true }, LDR) return result } -func (avl *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1 - - if idx1^idx2 < 0 { - if idx1 < 0 { - idx1 = avl.root.size + idx1 - 1 - } else { - idx2 = avl.root.size + idx2 - 1 - } - } - - if idx1 > idx2 { - ok = true - if idx1 >= avl.root.size { - idx1 = avl.root.size - 1 - ok = false - } - - n := avl.indexNode(idx1) - iter := NewIterator(n) - result = make([]interface{}, 0, idx1-idx2) - for i := idx2; i <= idx1; i++ { - if iter.Next() { - result = append(result, iter.Value()) - } else { - ok = false - return - } - } - - return - - } else { - ok = true - if idx2 >= avl.root.size { - idx2 = avl.root.size - 1 - ok = false - } - - if n := avl.indexNode(idx1); n != nil { - iter := NewIterator(n) - result = make([]interface{}, 0, idx2-idx1) - for i := idx1; i <= idx2; i++ { - if iter.Prev() { - result = append(result, iter.Value()) - } else { - ok = false - return - } - } - - return - } - - } - - return nil, false -} - -func (avl *Tree) GetRange(v1, v2 interface{}) { - c := avl.comparator(v2, v1) +func (tree *Tree) GetRange(v1, v2 interface{}) (result []interface{}) { + c := tree.comparator(v2, v1) switch c { case 1: - var min *Node - result := avl.getArountNode(v1) + + var min, max *Node + resultmin := tree.getArountNode(v1) + resultmax := tree.getArountNode(v2) for i := 1; i < 3 && min == nil; i++ { - min = result[i] + min = resultmin[i] } + + for i := 1; i > -1 && max == nil; i-- { + max = resultmax[i] + } + + if max == nil { + return []interface{}{} + } + + result = make([]interface{}, 0, 16) + + iter := NewIterator(min) + for iter.Prev() { + result = append(result, iter.Value()) + if iter.cur == max { + break + } + } + case -1: + + var min, max *Node + resultmin := tree.getArountNode(v2) + resultmax := tree.getArountNode(v1) + for i := 1; i < 3 && min == nil; i++ { + min = resultmin[i] + } + for i := 1; i > -1 && max == nil; i-- { + max = resultmax[i] + } + + if min == nil { + return []interface{}{} + } + + result = make([]interface{}, 0, 16) + + iter := NewIterator(max) + for iter.Next() { + result = append(result, iter.Value()) + if iter.cur == min { + break + } + } + case 0: + if n, ok := tree.GetNode(v1); ok { + return []interface{}{n.value} + } + return []interface{}{} } + + return } -func (avl *Tree) Get(value interface{}) (interface{}, bool) { - n, ok := avl.GetNode(value) +func (tree *Tree) Get(value interface{}) (interface{}, bool) { + n, ok := tree.GetNode(value) if ok { return n.value, true } return n, false } -func (avl *Tree) GetAround(value interface{}) (result [3]interface{}) { - an := avl.getArountNode(value) +func (tree *Tree) GetAround(value interface{}) (result [3]interface{}) { + an := tree.getArountNode(value) for i, n := range an { if n != nil { result[i] = n.value @@ -274,13 +326,13 @@ func (avl *Tree) GetAround(value interface{}) (result [3]interface{}) { return } -func (avl *Tree) getArountNode(value interface{}) (result [3]*Node) { +func (tree *Tree) getArountNode(value interface{}) (result [3]*Node) { var last *Node var lastc int - for n := avl.root; n != nil; { + for n := tree.root; n != nil; { last = n - c := avl.comparator(value, n.value) + c := tree.comparator(value, n.value) switch c { case -1: n = n.children[0] @@ -303,6 +355,16 @@ func (avl *Tree) getArountNode(value interface{}) (result [3]*Node) { if result[1] == nil { result[0] = last + + parent := last + 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 { l := result[1].children[il] r := result[1].children[ir] @@ -342,6 +404,16 @@ func (avl *Tree) getArountNode(value interface{}) (result [3]*Node) { if result[1] == nil { result[2] = last + + parent := last + 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 { l := result[1].children[il] @@ -410,10 +482,10 @@ func (avl *Tree) getArountNode(value interface{}) (result [3]*Node) { return } -func (avl *Tree) GetNode(value interface{}) (*Node, bool) { +func (tree *Tree) GetNode(value interface{}) (*Node, bool) { - for n := avl.root; n != nil; { - switch c := avl.comparator(value, n.value); c { + for n := tree.root; n != nil; { + switch c := tree.comparator(value, n.value); c { case -1: n = n.children[0] case 1: @@ -427,15 +499,15 @@ func (avl *Tree) GetNode(value interface{}) (*Node, bool) { return nil, false } -func (avl *Tree) Put(value interface{}) { +func (tree *Tree) Put(value interface{}) { node := &Node{value: value, size: 1} - if avl.root == nil { - avl.root = node + if tree.root == nil { + tree.root = node return } - cur := avl.root + cur := tree.root parent := cur.parent child := -1 @@ -449,7 +521,7 @@ func (avl *Tree) Put(value interface{}) { fsize := getSize(fixed) if fsize == 3 { lefts, rigths := getChildrenSize(fixed) - avl.fix3Size(fixed, lefts, rigths) + tree.fix3Size(fixed, lefts, rigths) } return } @@ -458,13 +530,13 @@ func (avl *Tree) Put(value interface{}) { 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 { - avl.fixSize(cur, ls, rs) + tree.fixSize(cur, ls, rs) } } cur.size++ parent = cur - c := avl.comparator(value, cur.value) + c := tree.comparator(value, cur.value) child = (c + 2) / 2 cur = cur.children[child] } @@ -493,8 +565,8 @@ const ( ) // Traversal 遍历的方法 -func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...interface{}) { - if avl.root == nil { +func (tree *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...interface{}) { + if tree.root == nil { return } @@ -521,7 +593,7 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } return true } - traverasl(avl.root) + traverasl(tree.root) case LDR: var traverasl func(cur *Node) bool traverasl = func(cur *Node) bool { @@ -540,7 +612,7 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } return true } - traverasl(avl.root) + traverasl(tree.root) case LRD: var traverasl func(cur *Node) bool traverasl = func(cur *Node) bool { @@ -558,7 +630,7 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } return true } - traverasl(avl.root) + traverasl(tree.root) case DRL: var traverasl func(cur *Node) bool traverasl = func(cur *Node) bool { @@ -576,7 +648,7 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } return true } - traverasl(avl.root) + traverasl(tree.root) case RDL: var traverasl func(cur *Node) bool traverasl = func(cur *Node) bool { @@ -594,7 +666,7 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } return true } - traverasl(avl.root) + traverasl(tree.root) case RLD: var traverasl func(cur *Node) bool traverasl = func(cur *Node) bool { @@ -612,11 +684,11 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } return true } - traverasl(avl.root) + traverasl(tree.root) } } -func (avl *Tree) lrrotate3(cur *Node) { +func (tree *Tree) lrrotate3(cur *Node) { const l = 1 const r = 0 @@ -639,7 +711,7 @@ func (avl *Tree) lrrotate3(cur *Node) { cur.children[l].size = 1 } -func (avl *Tree) lrrotate(cur *Node) { +func (tree *Tree) lrrotate(cur *Node) { const l = 1 const r = 0 @@ -679,7 +751,7 @@ func (avl *Tree) lrrotate(cur *Node) { cur.size = getChildrenSumSize(cur) + 1 } -func (avl *Tree) rlrotate3(cur *Node) { +func (tree *Tree) rlrotate3(cur *Node) { const l = 0 const r = 1 @@ -702,7 +774,7 @@ func (avl *Tree) rlrotate3(cur *Node) { cur.children[l].size = 1 } -func (avl *Tree) rlrotate(cur *Node) { +func (tree *Tree) rlrotate(cur *Node) { const l = 0 const r = 1 @@ -740,7 +812,7 @@ func (avl *Tree) rlrotate(cur *Node) { cur.size = getChildrenSumSize(cur) + 1 } -func (avl *Tree) rrotate3(cur *Node) { +func (tree *Tree) rrotate3(cur *Node) { const l = 0 const r = 1 // 1 right 0 left @@ -759,7 +831,7 @@ func (avl *Tree) rrotate3(cur *Node) { mov.size = 1 } -func (avl *Tree) rrotate(cur *Node) { +func (tree *Tree) rrotate(cur *Node) { const l = 0 const r = 1 @@ -793,7 +865,7 @@ func (avl *Tree) rrotate(cur *Node) { cur.size = getChildrenSumSize(cur) + 1 } -func (avl *Tree) lrotate3(cur *Node) { +func (tree *Tree) lrotate3(cur *Node) { const l = 1 const r = 0 // 1 right 0 left @@ -812,7 +884,7 @@ func (avl *Tree) lrotate3(cur *Node) { mov.size = 1 } -func (avl *Tree) lrotate(cur *Node) { +func (tree *Tree) lrotate(cur *Node) { const l = 1 const r = 0 @@ -861,56 +933,56 @@ func getSize(cur *Node) int { return cur.size } -func (avl *Tree) fixSizeWithRemove(cur *Node) { +func (tree *Tree) fixSizeWithRemove(cur *Node) { for cur != nil { cur.size-- if cur.size > 8 { ls, rs := getChildrenSize(cur) factor := cur.size / 10 // or factor = 1 if rs >= ls*2+factor || ls >= rs*2+factor { - avl.fixSize(cur, ls, rs) + tree.fixSize(cur, ls, rs) } } cur = cur.parent } } -func (avl *Tree) fix3Size(cur *Node, lefts, rigths int) { +func (tree *Tree) fix3Size(cur *Node, lefts, rigths int) { if lefts > rigths { l := cur.children[0] llsize, lrsize := getChildrenSize(l) if lrsize > llsize { - avl.rlrotate3(cur) + tree.rlrotate3(cur) } else { - avl.rrotate3(cur) + tree.rrotate3(cur) } } else { r := cur.children[1] rlsize, rrsize := getChildrenSize(r) if rlsize > rrsize { - avl.lrrotate3(cur) + tree.lrrotate3(cur) } else { - avl.lrotate3(cur) + tree.lrotate3(cur) } } } -func (avl *Tree) fixSize(cur *Node, lefts, rigths int) { +func (tree *Tree) fixSize(cur *Node, lefts, rigths int) { if lefts > rigths { l := cur.children[0] llsize, lrsize := getChildrenSize(l) if lrsize > llsize { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { r := cur.children[1] rlsize, rrsize := getChildrenSize(r) if rlsize > rrsize { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } } @@ -986,11 +1058,11 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { } } -func (avl *Tree) debugString() string { +func (tree *Tree) debugString() string { str := "AVLTree\n" - if avl.root == nil { + if tree.root == nil { return str + "nil" } - outputfordebug(avl.root, "", true, &str) + outputfordebug(tree.root, "", true, &str) return str } diff --git a/avlindex/avlindex_test.go b/avlindex/avlindex_test.go index 913201a..6aa689c 100644 --- a/avlindex/avlindex_test.go +++ b/avlindex/avlindex_test.go @@ -26,11 +26,7 @@ func TestSave(t *testing.T) { if err != nil { log.Println(err) } - - //fmt.Println(userBytes) - var l []int - // for i := 0; len(l) < 1000; i++ { // v := randomdata.Number(0, 65535) // l = append(l, v) @@ -251,6 +247,63 @@ func TestGet(t *testing.T) { } } +func TestGetRange(t *testing.T) { + tree := New(utils.IntComparator) + for _, v := range []int{5, 6, 8, 10, 13, 17, 1, 2, 40, 30} { + tree.Put(v) + } + + // t.Error(tree.debugString()) + // t.Error(tree.getArountNode(20)) + // t.Error(tree.Values()) + + result := tree.GetRange(0, 20) + if spew.Sprint(result) != "[1 2 5 6 8 10 13 17]" { + t.Error(result) + } + + result = tree.GetRange(-5, -1) + if spew.Sprint(result) != "[]" { + t.Error(result) + } + + result = tree.GetRange(7, 20) + if spew.Sprint(result) != "[8 10 13 17]" { + t.Error(result) + } + + result = tree.GetRange(30, 40) + if spew.Sprint(result) != "[30 40]" { + t.Error(result) + } + + result = tree.GetRange(30, 60) + if spew.Sprint(result) != "[30 40]" { + t.Error(result) + } + + result = tree.GetRange(40, 40) + if spew.Sprint(result) != "[40]" { + t.Error(result) + } + + result = tree.GetRange(50, 60) + if spew.Sprint(result) != "[]" { + t.Error(result) + } + + result = tree.GetRange(50, 1) + if spew.Sprint(result) != "[40 30 17 13 10 8 6 5 2 1]" { + t.Error(result) + } + + result = tree.GetRange(30, 20) + if spew.Sprint(result) != "[30]" { + t.Error(result) + } + +} + func TestTravalsal(t *testing.T) { tree := New(utils.IntComparator) @@ -375,6 +428,10 @@ func BenchmarkSkipListGet(b *testing.B) { } func BenchmarkGetRange(b *testing.B) { + +} + +func BenchmarkIndexRange(b *testing.B) { tree := New(utils.IntComparator) l := loadTestData() b.N = len(l) @@ -397,18 +454,18 @@ func BenchmarkGetRange(b *testing.B) { } func BenchmarkSkipListSet(b *testing.B) { - sl := skiplist.New(skiplist.Int) + l := loadTestData() - execCount := 50 + execCount := 1 b.N = len(l) * execCount for i := 0; i < execCount; i++ { + sl := skiplist.New(skiplist.Int) for _, v := range l { sl.Set(v, v) } } - } func BenchmarkIterator(b *testing.B) { @@ -564,7 +621,7 @@ func BenchmarkPut(b *testing.B) { b.ResetTimer() b.StartTimer() - execCount := 50 + execCount := 1 b.N = len(l) * execCount for i := 0; i < execCount; i++ { tree := New(utils.IntComparator)