From 51acc649a475fd0d8e381827cea783542987da14 Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Sun, 24 Mar 2019 22:21:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=A7=E9=83=A8=E5=88=86?= =?UTF-8?q?=E7=9A=84copy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- avl/avl_test.go | 95 +++--- avldup/avldup.go | 596 +++++++++++++++++++++++----------- avldup/avldup_test.go | 330 +++++++++---------- avldup/iterator.go | 154 ++++++--- avlkey/avlkey.go | 610 +++++++++++++++++++++++++---------- avlkey/avlkey_test.go | 292 +++++++++++------ avlkey/iterator.go | 153 ++++++--- avlkeydup/avlkeydup.go | 616 +++++++++++++++++++++++++----------- avlkeydup/avlkeydup_test.go | 329 +++++++++---------- avlkeydup/iterator.go | 153 ++++++--- for_test.go | 2 +- vbtkey/vbtkey_test.go | 114 +------ 12 files changed, 2173 insertions(+), 1271 deletions(-) diff --git a/avl/avl_test.go b/avl/avl_test.go index f3e3f57..13842ea 100644 --- a/avl/avl_test.go +++ b/avl/avl_test.go @@ -13,8 +13,6 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/trees/avltree" "github.com/emirpasic/gods/trees/redblacktree" - - "github.com/emirpasic/gods/utils" ) const CompartorSize = 100 @@ -59,10 +57,10 @@ func loadTestData() []int { } func TestIterator(t *testing.T) { - avl := New(utils.IntComparator) + tree := New(compare.Int) for _, v := range []int{1, 2, 7, 4, 5, 6, 7, 14, 15, 20, 30, 21, 3} { // t.Error(v) - avl.Put(v) + tree.Put(v) } // ` AVLTree @@ -80,7 +78,7 @@ func TestIterator(t *testing.T) { // └── 2 // └── 1` - iter := avl.Iterator() // root start point + iter := tree.Iterator() // root start point l := []int{14, 15, 20, 21, 30} for i := 0; iter.Next(); i++ { @@ -245,30 +243,29 @@ func TestGetAround(t *testing.T) { // for test error case func TestPutStable(t *testing.T) { - f, _ := os.OpenFile("./test.log", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666) - log.SetOutput(f) + // f, _ := os.OpenFile("./test.log", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666) + // log.SetOutput(f) // 0-1 3 | 2-3 7-8 | 4-7 12-16 | 8-15 20-32 | 16-31 33-58 l := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 19, 20, 21, 22, 30, 41, 41, 41} - for i := 0; i < 100000; i++ { - var l []int - for len(l) < 1000 { - l = append(l, randomdata.Number(0, 100)) - } + // for i := 0; i < 100000; i++ { + // var l []int + // for len(l) < 1000 { + // l = append(l, randomdata.Number(0, 100)) + // } - avl := New(utils.IntComparator) - for _, v := range l { - avl.Put(v) - } - } - - // t.Error(avl.debugString(), avl.TraversalBreadth(), "\n", "-----------") + // tree := New(compare.Int) + // for _, v := range l { + // tree.Put(v) + // } + // } + // t.Error(tree.debugString(), tree.TraversalBreadth(), "\n", "-----------") } func TestPutComparatorRandom(t *testing.T) { for n := 0; n < 300000; n++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) godsavl := avltree.NewWithIntComparator() content := "" @@ -278,14 +275,14 @@ func TestPutComparatorRandom(t *testing.T) { if _, ok := m[v]; !ok { m[v] = v content += spew.Sprint(v) + "," - avl.Put(v) + tree.Put(v) godsavl.Put(v, v) } } - if avl.String() != godsavl.String() { + if tree.String() != godsavl.String() { t.Error(godsavl.String()) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(content, n) break } @@ -293,9 +290,9 @@ func TestPutComparatorRandom(t *testing.T) { } func TestGet(t *testing.T) { - avl := New(utils.IntComparator) + tree := New(compare.Int) for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - avl.Put(v) + tree.Put(v) } result := ` @@ -311,21 +308,21 @@ func TestGet(t *testing.T) { └── 1562 ` - s1 := avl.String() + s1 := tree.String() s2 := "AVLTree" + result if s1 != s2 { t.Error(s1, s2) } for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - v, ok := avl.Get(v) + v, ok := tree.Get(v) if !ok { t.Error("the val not found ", v) } } - if v, ok := avl.Get(10000); ok { - t.Error("the val(1000) is not in tree, but is found", v) + if v, ok := tree.Get(10000); ok { + t.Error("the val(10000) is not in tree, but is found", v) } } @@ -334,7 +331,7 @@ func TestRemoveAll(t *testing.T) { ALL: for c := 0; c < 5000; c++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) gods := avltree.NewWithIntComparator() var l []int m := make(map[int]int) @@ -344,18 +341,18 @@ ALL: if _, ok := m[v]; !ok { m[v] = v l = append(l, v) - avl.Put(v) + tree.Put(v) gods.Put(v, v) } } for i := 0; i < 100; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - s1 := spew.Sprint(avl.Values()) + s1 := spew.Sprint(tree.Values()) s2 := spew.Sprint(gods.Values()) if s1 != s2 { - t.Error("avl remove error", "avlsize = ", avl.Size()) + t.Error("avl remove error", "avlsize = ", tree.Size()) t.Error(s1) t.Error(s2) break ALL @@ -369,7 +366,7 @@ func TestRemove(t *testing.T) { ALL: for N := 0; N < 500000; N++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) gods := avltree.NewWithIntComparator() var l []int @@ -380,25 +377,25 @@ ALL: if _, ok := m[v]; !ok { l = append(l, v) m[v] = v - avl.Put(v) + tree.Put(v) gods.Put(v, v) } } - src1 := avl.String() + src1 := tree.String() src2 := gods.String() for i := 0; i < 10; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - if spew.Sprint(gods.Values()) != spew.Sprint(avl.Values()) && avl.size != 0 { - // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { + if spew.Sprint(gods.Values()) != spew.Sprint(tree.Values()) && tree.size != 0 { + // if gods.String() != tree.String() && gods.Size() != 0 && tree.size != 0 { t.Error(src1) t.Error(src2) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(gods.String()) t.Error(l[i]) - // t.Error(avl.TraversalDepth(-1)) + // t.Error(tree.TraversalDepth(-1)) // t.Error(gods.Values()) break ALL } @@ -407,7 +404,7 @@ ALL: } func BenchmarkIterator(b *testing.B) { - tree := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() @@ -435,7 +432,7 @@ func BenchmarkIterator(b *testing.B) { } func BenchmarkRemove(b *testing.B) { - tree := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() @@ -490,7 +487,7 @@ func BenchmarkGodsRBRemove(b *testing.B) { func BenchmarkGet(b *testing.B) { - avl := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() b.N = len(l) @@ -498,7 +495,7 @@ func BenchmarkGet(b *testing.B) { b.ResetTimer() b.StartTimer() for i := 0; i < b.N; i++ { - avl.Get(l[i]) + tree.Get(l[i]) } } @@ -538,12 +535,12 @@ func BenchmarkPut(b *testing.B) { execCount := 50 b.N = len(l) * execCount for i := 0; i < execCount; i++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) for _, v := range l { - avl.Put(v) + tree.Put(v) } } - // b.Log(avl.count) + // b.Log(tree.count) } func BenchmarkGodsRBPut(b *testing.B) { diff --git a/avldup/avldup.go b/avldup/avldup.go index eb29a08..faffdb7 100644 --- a/avldup/avldup.go +++ b/avldup/avldup.go @@ -1,9 +1,8 @@ package avldup import ( + "474420502.top/eson/structure/compare" "github.com/davecgh/go-spew/spew" - - "github.com/emirpasic/gods/utils" ) type Node struct { @@ -13,13 +12,6 @@ type Node struct { value interface{} } -// func (n *Node) String() string { -// if n == nil { -// return "nil" -// } -// return spew.Sprint(n.value) -// } - func (n *Node) String() string { if n == nil { return "nil" @@ -33,40 +25,40 @@ func (n *Node) String() string { } type Tree struct { - root *Node - size int - comparator utils.Comparator + root *Node + size int + compare compare.Compare } -func New(comparator utils.Comparator) *Tree { - return &Tree{comparator: comparator} +func New(compare compare.Compare) *Tree { + return &Tree{compare: compare} } -func (avl *Tree) String() string { - if avl.size == 0 { +func (tree *Tree) String() string { + if tree.size == 0 { return "" } str := "AVLTree\n" - 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 { - return avl.size +func (tree *Tree) Size() int { + return tree.size } -func (avl *Tree) Remove(value interface{}) *Node { +func (tree *Tree) Remove(key interface{}) *Node { - if n, ok := avl.GetNode(value); ok { + if n, ok := tree.GetNode(key); ok { - avl.size-- - if avl.size == 0 { - avl.root = nil + tree.size-- + if tree.size == 0 { + tree.root = nil return n } @@ -76,7 +68,7 @@ func (avl *Tree) Remove(value interface{}) *Node { if left == -1 && right == -1 { p := n.parent p.children[getRelationship(n)] = nil - avl.fixRemoveHeight(p) + tree.fixRemoveHeight(p) return n } @@ -113,9 +105,9 @@ func (avl *Tree) Remove(value interface{}) *Node { // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 if cparent == n { - avl.fixRemoveHeight(n) + tree.fixRemoveHeight(n) } else { - avl.fixRemoveHeight(cparent) + tree.fixRemoveHeight(cparent) } return cur @@ -124,16 +116,94 @@ func (avl *Tree) Remove(value interface{}) *Node { return nil } -func (avl *Tree) Get(key interface{}) (interface{}, bool) { - n, ok := avl.GetNode(key) +// Values 返回先序遍历的值 +func (tree *Tree) Values() []interface{} { + mszie := 0 + if tree.root != nil { + mszie = tree.size + } + result := make([]interface{}, 0, mszie) + tree.Traversal(func(v interface{}) bool { + result = append(result, v) + return true + }, LDR) + return result +} + +func (tree *Tree) GetRange(k1, k2 interface{}) (result []interface{}) { + c := tree.compare(k2, k1) + switch c { + case 1: + + var min, max *Node + resultmin := tree.getArountNode(k1) + resultmax := tree.getArountNode(k2) + for i := 1; i < 3 && min == nil; 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.Next() { + result = append(result, iter.Value()) + if iter.cur == max { + break + } + } + case -1: + + var min, max *Node + resultmin := tree.getArountNode(k2) + resultmax := tree.getArountNode(k1) + 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.Prev() { + result = append(result, iter.Value()) + if iter.cur == min { + break + } + } + case 0: + if n, ok := tree.GetNode(k1); ok { + return []interface{}{n.value} + } + return []interface{}{} + } + + return +} + +func (tree *Tree) Get(key interface{}) (interface{}, bool) { + n, ok := tree.GetNode(key) if ok { return n.value, true } return n, false } -func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { - an := avl.GetAroundNode(key) +func (tree *Tree) GetAround(key interface{}) (result [3]interface{}) { + an := tree.getArountNode(key) for i, n := range an { if n != nil { result[i] = n.value @@ -142,63 +212,65 @@ func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { return } -func (avl *Tree) GetAroundNode(value interface{}) (result [3]*Node) { - n := avl.root +func (tree *Tree) getArountNode(key interface{}) (result [3]*Node) { + var last *Node + var lastc int - for { + for n := tree.root; n != nil; { + last = n + c := tree.compare(key, 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 compare only is allowed in -1, 0, 1") + } + } - if n == nil { + switch lastc { + case 1: + + if result[1] != nil { + + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) + } else { + result[0] = last + result[2] = GetNext(last, 1) + } + + case -1: + + if result[1] != nil { + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) + } else { + result[2] = last + result[0] = GetPrev(last, 1) + } + + case 0: + + if result[1] == nil { return } - - 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: - - 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") - } - + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) } + return } -func (avl *Tree) GetNode(value interface{}) (*Node, bool) { - for n := avl.root; n != nil; { - switch c := avl.comparator(value, n.value); c { +func (tree *Tree) GetNode(value interface{}) (*Node, bool) { + + for n := tree.root; n != nil; { + switch c := tree.compare(value, n.value); c { case -1: n = n.children[0] case 1: @@ -206,99 +278,192 @@ func (avl *Tree) GetNode(value interface{}) (*Node, bool) { case 0: return n, true default: - panic("Get comparator only is allowed in -1, 0, 1") + panic("Get compare only is allowed in -1, 0, 1") } } return nil, false } -func (avl *Tree) Put(value interface{}) { - - if avl.size == 0 { - avl.root = &Node{value: value} - avl.size++ +func (tree *Tree) Put(value interface{}) { + tree.size++ + node := &Node{value: value} + if tree.size == 1 { + tree.root = node return } - cur := avl.root + cur := tree.root parent := cur.parent child := -1 for { if cur == nil { - avl.size++ - node := &Node{value: value} parent.children[child] = node node.parent = parent if node.parent.height == 0 { - avl.fixPutHeight(node.parent) + tree.fixPutHeight(node.parent) } return } parent = cur - c := avl.comparator(value, cur.value) + c := tree.compare(value, cur.value) + if c == 0 { + cur.value = value + return + } child = (c + 2) / 2 cur = cur.children[child] } - } -func (avl *Tree) debugString() string { - if avl.size == 0 { - return "" +type TraversalMethod int + +const ( + // L = left R = right D = Value(dest) + _ TraversalMethod = iota + //DLR 先值 然后左递归 右递归 下面同理 + DLR + //LDR 先从左边有序访问到右边 从小到大 + LDR + // LRD 同理 + LRD + + // DRL 同理 + DRL + + // RDL 先从右边有序访问到左边 从大到小 + RDL + + // RLD 同理 + RLD +) + +// Traversal 遍历的方法 默认是LDR 从小到大 compare 为 l < r +func (tree *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...interface{}) { + if tree.root == nil { + return } - str := "AVLTree\n" - outputfordebug(avl.root, "", true, &str) - 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]) + method := LDR + if len(traversalMethod) != 0 { + method = traversalMethod[0].(TraversalMethod) } - traverasl(avl.root) - return -} -func (avl *Tree) TraversalDepth(leftright int) (result []interface{}) { - result = make([]interface{}, 0, avl.size) - if leftright < 0 { - var traverasl func(cur *Node) - traverasl = func(cur *Node) { + switch method { + case DLR: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { if cur == nil { - return + return true } - traverasl(cur.children[0]) - result = append(result, cur.value) - traverasl(cur.children[1]) + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true } - traverasl(avl.root) - } else { - var traverasl func(cur *Node) - traverasl = func(cur *Node) { + traverasl(tree.root) + case LDR: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { if cur == nil { - return + return true } - traverasl(cur.children[1]) - result = append(result, cur.value) - traverasl(cur.children[0]) + if !traverasl(cur.children[0]) { + return false + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true } - traverasl(avl.root) + traverasl(tree.root) + case LRD: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + if !every(cur.value) { + return false + } + return true + } + traverasl(tree.root) + case DRL: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true + } + traverasl(tree.root) + case RDL: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[1]) { + return false + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + return true + } + traverasl(tree.root) + case RLD: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[1]) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !every(cur.value) { + return false + } + return true + } + traverasl(tree.root) } - - return } -func (avl *Tree) lrrotate(cur *Node) { +func (tree *Tree) lrrotate(cur *Node) { const l = 1 const r = 0 @@ -333,12 +498,16 @@ func (avl *Tree) lrrotate(cur *Node) { cur.children[r] = mov mov.parent = cur + // movparent.size = getChildrenSumSize(movparent) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) rlrotate(cur *Node) { +func (tree *Tree) rlrotate(cur *Node) { const l = 0 const r = 1 @@ -371,30 +540,31 @@ func (avl *Tree) rlrotate(cur *Node) { cur.children[r] = mov mov.parent = cur + // movparent.size = getChildrenSumSize(movparent) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) rrotate(cur *Node) { +func (tree *Tree) rrotateex(cur *Node) { const l = 0 const r = 1 // 1 right 0 left mov := cur.children[l] - + if mov == nil { + return + } mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - // if mov.children[l] != nil { - // mov.children[l].parent = cur - // cur.children[l] = mov.children[l] - // } else { - // cur.children[l] = nil - // } - - // 不可能为nil - mov.children[l].parent = cur + // mov.children[l]不可能为nil cur.children[l] = mov.children[l] + if mov.children[l] != nil { + mov.children[l].parent = cur + } // 解决mov节点孩子转移的问题 if mov.children[r] != nil { @@ -417,7 +587,83 @@ func (avl *Tree) rrotate(cur *Node) { cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) lrotate(cur *Node) { +func (tree *Tree) rrotate(cur *Node) { + + const l = 0 + const r = 1 + // 1 right 0 left + mov := cur.children[l] + + mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 + + // mov.children[l]不可能为nil + mov.children[l].parent = cur + cur.children[l] = mov.children[l] + + // 解决mov节点孩子转移的问题 + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + } else { + mov.children[l] = nil + } + + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.children[r] = mov + + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + + mov.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + +func (tree *Tree) lrotateex(cur *Node) { + + const l = 1 + const r = 0 + + mov := cur.children[l] + if mov == nil { + return + } + mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 + + // 不可能为nil + cur.children[l] = mov.children[l] + if mov.children[l] != nil { + mov.children[l].parent = cur + } + + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + } else { + mov.children[l] = nil + } + + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } + + cur.children[r] = mov + + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + + mov.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + +func (tree *Tree) lrotate(cur *Node) { const l = 1 const r = 0 @@ -426,13 +672,6 @@ func (avl *Tree) lrotate(cur *Node) { mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - // if mov.children[l] != nil { - // mov.children[l].parent = cur - // cur.children[l] = mov.children[l] - // } else { - // cur.children[l] = nil - // } - // 不可能为nil mov.children[l].parent = cur cur.children[l] = mov.children[l] @@ -452,6 +691,9 @@ func (avl *Tree) lrotate(cur *Node) { cur.children[r] = mov + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } @@ -484,42 +726,35 @@ func getHeight(cur *Node) int { return cur.height } -func (avl *Tree) fixRemoveHeight(cur *Node) { - +func (tree *Tree) fixRemoveHeight(cur *Node) { for { lefth, rigthh, lrmax := getMaxAndChildrenHeight(cur) // 判断当前节点是否有变化, 如果没变化的时候, 不需要往上修复 - isBreak := false - if cur.height == lrmax+1 { - isBreak = true - } else { - cur.height = lrmax + 1 - } + curheight := lrmax + 1 + cur.height = curheight // 计算高度的差值 绝对值大于2的时候需要旋转 diff := lefth - rigthh if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } else if diff > 1 { l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { - - if isBreak { + if cur.height == curheight { return } - } if cur.parent == nil { @@ -531,7 +766,7 @@ func (avl *Tree) fixRemoveHeight(cur *Node) { } -func (avl *Tree) fixPutHeight(cur *Node) { +func (tree *Tree) fixPutHeight(cur *Node) { for { @@ -543,16 +778,16 @@ func (avl *Tree) fixPutHeight(cur *Node) { if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } else if diff > 1 { l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { @@ -641,3 +876,12 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { outputfordebug(node.children[0], newPrefix, true, str) } } + +func (tree *Tree) debugString() string { + if tree.size == 0 { + return "" + } + str := "AVLTree\n" + outputfordebug(tree.root, "", true, &str) + return str +} diff --git a/avldup/avldup_test.go b/avldup/avldup_test.go index 51c404c..abcaf17 100644 --- a/avldup/avldup_test.go +++ b/avldup/avldup_test.go @@ -5,9 +5,9 @@ import ( "encoding/gob" "io/ioutil" "log" - "os" "testing" + "474420502.top/eson/structure/compare" "github.com/Pallinder/go-randomdata" "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/trees/avltree" @@ -16,36 +16,6 @@ import ( "github.com/emirpasic/gods/utils" ) -const CompartorSize = 500000 -const NumberMax = 60000000 - -func TestSave(t *testing.T) { - - f, err := os.OpenFile("../l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) - if err != nil { - log.Println(err) - } - - //fmt.Println(userBytes) - - var l []int - m := make(map[int]int) - for i := 0; len(l) < CompartorSize; i++ { - v := randomdata.Number(0, NumberMax) - if _, ok := m[v]; !ok { - m[v] = v - l = append(l, v) - } - } - - var result bytes.Buffer - encoder := gob.NewEncoder(&result) - encoder.Encode(l) - lbytes := result.Bytes() - f.Write(lbytes) - -} - func loadTestData() []int { data, err := ioutil.ReadFile("../l.log") if err != nil { @@ -57,125 +27,145 @@ func loadTestData() []int { return l } -func TestDupKey(t *testing.T) { - tree1 := New(utils.IntComparator) - tree2 := avltree.NewWithIntComparator() - - for i := 0; i < CompartorSize/1000; i++ { - v := randomdata.Number(0, NumberMax) - tree1.Put(v) - tree2.Put(v, v) +func TestGetRange(t *testing.T) { + tree := New(compare.Int) + for _, v := range []int{5, 6, 8, 10, 13, 17, 1, 2, 40, 30} { + tree.Put(v) } - tree1.Put(500) - tree2.Put(500, 500) + // t.Error(tree.debugString()) + // t.Error(tree.getArountNode(20)) + // t.Error(tree.Values()) - tree1.Put(500) - tree2.Put(500, 500) - - if tree1.Size() == tree2.Size() { - t.Error("tree size is equal") + result := tree.GetRange(0, 20) + if spew.Sprint(result) != "[1 2 5 6 8 10 13 17]" { + t.Error(result) } - if tree1.String() == tree2.String() { - t.Error(tree1.String()) - } -} - -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) - - } - // ` AVLTree - // │ ┌── 30 - // │ │ └── 21 - // │ ┌── 20 - // │ │ └── 15 - // └── 14 - // │ ┌── 7 - // │ ┌── 7 - // │ │ └── 6 - // └── 5 - // │ ┌── 4 - // │ │ └── 3 - // └── 2 - // └── 1` - - iter := avl.Iterator() // root start point - - l := []int{14, 15, 20, 21, 30} - - for i := 0; iter.Prev(); i++ { - if iter.Value().(int) != l[i] { - t.Error("iter prev error", iter.Value(), l[i]) - } + result = tree.GetRange(-5, -1) + if spew.Sprint(result) != "[]" { + t.Error(result) } - iter.Prev() - if iter.Value().(int) != 30 { - t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value()) + result = tree.GetRange(7, 20) + if spew.Sprint(result) != "[8 10 13 17]" { + t.Error(result) } - 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()) - } + result = tree.GetRange(30, 40) + if spew.Sprint(result) != "[30 40]" { + t.Error(result) } - 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()) + result = tree.GetRange(30, 60) + if spew.Sprint(result) != "[30 40]" { + t.Error(result) } - if iter.Prev() != true && iter.Value().(int) != 2 { - t.Error("next to prev is error") + 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 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) + tree := New(compare.Int) + for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} { + tree.Put(v) } - if spew.Sprint(avl.GetAround(30)) != "[40 30 21]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(30))) + var Result string + + Result = spew.Sprint(tree.GetAround(14)) + if Result != "[7 14 15]" { + t.Error(tree.Values()) + t.Error("17 is root, tree.GetAround(14)) is error", Result) + t.Error(tree.debugString()) } - if spew.Sprint(avl.GetAround(40)) != "[40 40 30]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50))) + Result = spew.Sprint(tree.GetAround(17)) + if Result != "[16 17 20]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(17)) is error", Result) + t.Error(tree.debugString()) } - if spew.Sprint(avl.GetAround(50)) != "[ 50 40]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50))) + Result = spew.Sprint(tree.GetAround(3)) + if Result != "[ 3 7]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(3)) is error", Result) + t.Error(tree.debugString()) } + + Result = spew.Sprint(tree.GetAround(40)) + if Result != "[30 40 50]" { + 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 ]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(50)) is error", Result) + t.Error(tree.debugString()) + } + + Result = spew.Sprint(tree.GetAround(18)) + if Result != "[17 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 7]" { + 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 != "[ 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 ]" { + 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 func TestPutStable(t *testing.T) { - // avl := New(utils.IntComparator) - // gods := avltree.NewWithIntComparator() - // // 44908, 34985, 62991, 4201, 27210, 30707 - // for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - // t.Error(v) - // t.Error(avl.debugString()) - // avl.Put(v) - // gods.Put(v, v) - // t.Error(avl.debugString()) - // t.Error(gods.String()) - // } + // t.Error(tree.debugString(), tree.TraversalBreadth(), "\n", "-----------") } func TestPutComparatorRandom(t *testing.T) { for n := 0; n < 300000; n++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) godsavl := avltree.NewWithIntComparator() content := "" @@ -185,16 +175,14 @@ func TestPutComparatorRandom(t *testing.T) { if _, ok := m[v]; !ok { m[v] = v content += spew.Sprint(v) + "," - // t.Error(v) - avl.Put(v) - // t.Error(avl.String()) + tree.Put(v) godsavl.Put(v, v) } } - if avl.String() != godsavl.String() { + if tree.String() != godsavl.String() { t.Error(godsavl.String()) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(content, n) break } @@ -202,9 +190,9 @@ func TestPutComparatorRandom(t *testing.T) { } func TestGet(t *testing.T) { - avl := New(utils.IntComparator) + tree := New(compare.Int) for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - avl.Put(v) + tree.Put(v) } result := ` @@ -220,21 +208,21 @@ func TestGet(t *testing.T) { └── 1562 ` - s1 := avl.String() + s1 := tree.String() s2 := "AVLTree" + result if s1 != s2 { t.Error(s1, s2) } for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - v, ok := avl.Get(v) + v, ok := tree.Get(v) if !ok { t.Error("the val not found ", v) } } - if v, ok := avl.Get(10000); ok { - t.Error("the val(1000) is not in tree, but is found", v) + if v, ok := tree.Get(10000); ok { + t.Error("the val(10000) is not in tree, but is found", v) } } @@ -243,7 +231,7 @@ func TestRemoveAll(t *testing.T) { ALL: for c := 0; c < 5000; c++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) gods := avltree.NewWithIntComparator() var l []int m := make(map[int]int) @@ -253,32 +241,32 @@ ALL: if _, ok := m[v]; !ok { m[v] = v l = append(l, v) - avl.Put(v) + tree.Put(v) gods.Put(v, v) } } for i := 0; i < 100; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - s1 := spew.Sprint(avl.TraversalDepth(-1)) + s1 := spew.Sprint(tree.Values()) s2 := spew.Sprint(gods.Values()) if s1 != s2 { - t.Error("avl remove error", "avlsize = ", avl.Size()) + t.Error("avl remove error", "avlsize = ", tree.Size()) t.Error(s1) t.Error(s2) break ALL } } } + } func TestRemove(t *testing.T) { ALL: - for N := 0; N < 500000; N++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) gods := avltree.NewWithIntComparator() var l []int @@ -289,25 +277,25 @@ ALL: if _, ok := m[v]; !ok { l = append(l, v) m[v] = v - avl.Put(v) + tree.Put(v) gods.Put(v, v) } } - src1 := avl.String() + src1 := tree.String() src2 := gods.String() for i := 0; i < 10; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - if spew.Sprint(gods.Values()) != spew.Sprint(avl.TraversalDepth(-1)) && avl.size != 0 { - // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { + if spew.Sprint(gods.Values()) != spew.Sprint(tree.Values()) && tree.size != 0 { + // if gods.String() != tree.String() && gods.Size() != 0 && tree.size != 0 { t.Error(src1) t.Error(src2) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(gods.String()) t.Error(l[i]) - // t.Error(avl.TraversalDepth(-1)) + // t.Error(tree.TraversalDepth(-1)) // t.Error(gods.Values()) break ALL } @@ -319,7 +307,6 @@ func BenchmarkIterator(b *testing.B) { tree := New(utils.IntComparator) l := loadTestData() - b.N = len(l) for _, v := range l { tree.Put(v) @@ -327,35 +314,21 @@ func BenchmarkIterator(b *testing.B) { b.ResetTimer() b.StartTimer() + b.N = 0 iter := tree.Iterator() for iter.Next() { + b.N++ } for iter.Prev() { + b.N++ } 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() { + b.N++ } for iter.Prev() { + b.N++ } - for iter.Next() { - } + } func BenchmarkRemove(b *testing.B) { @@ -363,15 +336,16 @@ func BenchmarkRemove(b *testing.B) { l := loadTestData() - b.N = len(l) for _, v := range l { tree.Put(v) } + ll := tree.Values() + b.N = len(ll) b.ResetTimer() b.StartTimer() - for i := 0; i < len(l); i++ { + for i := 0; i < len(ll); i++ { tree.Remove(l[i]) } } @@ -386,10 +360,12 @@ func BenchmarkGodsRemove(b *testing.B) { tree.Put(v, v) } + ll := tree.Values() + b.N = len(ll) b.ResetTimer() b.StartTimer() - for i := 0; i < len(l); i++ { + for i := 0; i < len(ll); i++ { tree.Remove(l[i]) } } @@ -404,17 +380,20 @@ func BenchmarkGodsRBRemove(b *testing.B) { tree.Put(v, v) } + ll := tree.Values() + b.N = len(ll) + b.ResetTimer() b.StartTimer() - for i := 0; i < len(l); i++ { + for i := 0; i < len(ll); i++ { tree.Remove(l[i]) } } func BenchmarkGet(b *testing.B) { - avl := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() b.N = len(l) @@ -422,7 +401,7 @@ func BenchmarkGet(b *testing.B) { b.ResetTimer() b.StartTimer() for i := 0; i < b.N; i++ { - avl.Get(l[i]) + tree.Get(l[i]) } } @@ -453,18 +432,21 @@ func BenchmarkGodsAvlGet(b *testing.B) { } func BenchmarkPut(b *testing.B) { - avl := New(utils.IntComparator) l := loadTestData() b.ResetTimer() b.StartTimer() - b.N = len(l) - for _, v := range l { - avl.Put(v) + execCount := 50 + b.N = len(l) * execCount + for i := 0; i < execCount; i++ { + tree := New(compare.Int) + for _, v := range l { + tree.Put(v) + } } - + // b.Log(tree.count) } func BenchmarkGodsRBPut(b *testing.B) { diff --git a/avldup/iterator.go b/avldup/iterator.go index 3d9c9ca..303ce57 100644 --- a/avldup/iterator.go +++ b/avldup/iterator.go @@ -5,21 +5,24 @@ import ( ) type Iterator struct { - op *Tree - dir int up *Node cur *Node tstack *lastack.Stack - // curnext *Node } 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(n *Node) *Iterator { + iter := &Iterator{tstack: lastack.New()} + iter.up = n + return iter +} + func (iter *Iterator) Value() interface{} { return iter.cur.value } @@ -42,46 +45,47 @@ func (iter *Iterator) Right() bool { return false } -func (iter *Iterator) Prev() (result bool) { +func GetNext(cur *Node, idx int) *Node { - 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 := 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) } - iter.dir = -1 - } - if iter.tstack.Size() == 0 { - if iter.up == nil { - return false + 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 } - 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 + return cur } func (iter *Iterator) Next() (result bool) { - if iter.dir < 1 { // 非 1(next 方向定义 -1 为 prev) - if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 + if iter.dir > -1 { + if iter.dir == 1 && iter.cur != nil { iter.tstack.Clear() - iter.curPushNextStack(iter.cur) // 把当前cur计算的逆向回朔 - iter.up = iter.getNextUp(iter.cur) // cur 寻找下个要计算up + iter.curPushNextStack(iter.cur) + iter.up = iter.getNextUp(iter.cur) } - iter.dir = 1 + iter.dir = -1 } - // 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值 if iter.tstack.Size() == 0 { if iter.up == nil { return false @@ -96,6 +100,64 @@ func (iter *Iterator) Next() (result bool) { return true } + 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 { // 非 1(next 方向定义 -1 为 prev) + if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 + iter.tstack.Clear() + iter.curPushPrevStack(iter.cur) // 把当前cur计算的逆向回朔 + iter.up = iter.getPrevUp(iter.cur) // cur 寻找下个要计算up + } + iter.dir = 1 + } + + // 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值 + 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 + } + // 如果再次计算的栈为空, 则只能返回false return false } @@ -107,7 +169,7 @@ func getRelationship(cur *Node) int { return 0 } -func (iter *Iterator) getNextUp(cur *Node) *Node { +func (iter *Iterator) getPrevUp(cur *Node) *Node { for cur.parent != nil { if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序 return cur.parent @@ -117,19 +179,19 @@ func (iter *Iterator) getNextUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushNextStack(cur *Node) { - next := cur.children[0] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值 +func (iter *Iterator) curPushPrevStack(cur *Node) { + Prev := 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) // 入栈 用于回溯 + if Prev != nil { + iter.tstack.Push(Prev) + for Prev.children[1] != nil { + Prev = Prev.children[1] + iter.tstack.Push(Prev) // 入栈 用于回溯 } } } -func (iter *Iterator) getPrevUp(cur *Node) *Node { +func (iter *Iterator) getNextUp(cur *Node) *Node { for cur.parent != nil { if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序 return cur.parent @@ -139,14 +201,14 @@ func (iter *Iterator) getPrevUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushPrevStack(cur *Node) { - prev := cur.children[1] +func (iter *Iterator) curPushNextStack(cur *Node) { + next := cur.children[1] - if prev != nil { - iter.tstack.Push(prev) - for prev.children[0] != nil { - prev = prev.children[0] - iter.tstack.Push(prev) + if next != nil { + iter.tstack.Push(next) + for next.children[0] != nil { + next = next.children[0] + iter.tstack.Push(next) } } } diff --git a/avlkey/avlkey.go b/avlkey/avlkey.go index c70f838..1d5ceb9 100644 --- a/avlkey/avlkey.go +++ b/avlkey/avlkey.go @@ -1,9 +1,8 @@ package avlkey import ( + "474420502.top/eson/structure/compare" "github.com/davecgh/go-spew/spew" - - "github.com/emirpasic/gods/utils" ) type Node struct { @@ -13,13 +12,6 @@ type Node struct { key, value interface{} } -// func (n *Node) String() string { -// if n == nil { -// return "nil" -// } -// return spew.Sprint(n.value) -// } - func (n *Node) String() string { if n == nil { return "nil" @@ -33,40 +25,40 @@ func (n *Node) String() string { } type Tree struct { - root *Node - size int - comparator utils.Comparator + root *Node + size int + compare compare.Compare } -func New(comparator utils.Comparator) *Tree { - return &Tree{comparator: comparator} +func New(compare compare.Compare) *Tree { + return &Tree{compare: compare} } -func (avl *Tree) String() string { - if avl.size == 0 { +func (tree *Tree) String() string { + if tree.size == 0 { return "" } str := "AVLTree\n" - 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 { - return avl.size +func (tree *Tree) Size() int { + return tree.size } -func (avl *Tree) Remove(key interface{}) *Node { +func (tree *Tree) Remove(key interface{}) *Node { - if n, ok := avl.GetNode(key); ok { + if n, ok := tree.GetNode(key); ok { - avl.size-- - if avl.size == 0 { - avl.root = nil + tree.size-- + if tree.size == 0 { + tree.root = nil return n } @@ -76,7 +68,7 @@ func (avl *Tree) Remove(key interface{}) *Node { if left == -1 && right == -1 { p := n.parent p.children[getRelationship(n)] = nil - avl.fixRemoveHeight(p) + tree.fixRemoveHeight(p) return n } @@ -113,9 +105,9 @@ func (avl *Tree) Remove(key interface{}) *Node { // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 if cparent == n { - avl.fixRemoveHeight(n) + tree.fixRemoveHeight(n) } else { - avl.fixRemoveHeight(cparent) + tree.fixRemoveHeight(cparent) } return cur @@ -124,16 +116,94 @@ func (avl *Tree) Remove(key interface{}) *Node { return nil } -func (avl *Tree) Get(key interface{}) (interface{}, bool) { - n, ok := avl.GetNode(key) +// Values 返回先序遍历的值 +func (tree *Tree) Values() []interface{} { + mszie := 0 + if tree.root != nil { + mszie = tree.size + } + result := make([]interface{}, 0, mszie) + tree.Traversal(func(v interface{}) bool { + result = append(result, v) + return true + }, LDR) + return result +} + +func (tree *Tree) GetRange(k1, k2 interface{}) (result []interface{}) { + c := tree.compare(k2, k1) + switch c { + case 1: + + var min, max *Node + resultmin := tree.getArountNode(k1) + resultmax := tree.getArountNode(k2) + for i := 1; i < 3 && min == nil; 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.Next() { + result = append(result, iter.Value()) + if iter.cur == max { + break + } + } + case -1: + + var min, max *Node + resultmin := tree.getArountNode(k2) + resultmax := tree.getArountNode(k1) + 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.Prev() { + result = append(result, iter.Value()) + if iter.cur == min { + break + } + } + case 0: + if n, ok := tree.GetNode(k1); ok { + return []interface{}{n.value} + } + return []interface{}{} + } + + return +} + +func (tree *Tree) Get(key interface{}) (interface{}, bool) { + n, ok := tree.GetNode(key) if ok { return n.value, true } return n, false } -func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { - an := avl.GetAroundNode(key) +func (tree *Tree) GetAround(key interface{}) (result [3]interface{}) { + an := tree.getArountNode(key) for i, n := range an { if n != nil { result[i] = n.value @@ -142,85 +212,105 @@ func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { return } -func (avl *Tree) GetAroundNode(key interface{}) (result [3]*Node) { - n := avl.root +func (tree *Tree) getArountNode(key interface{}) (result [3]*Node) { + var last *Node + var lastc int - for { + for n := tree.root; n != nil; { + last = n + c := tree.compare(key, n.value) + switch c { + case -1: + n = n.children[0] + lastc = c + case 1: + n = n.children[1] + lastc = c + case 0: + iter := NewIterator(n) + iter.Prev() + for iter.Prev() { + if tree.compare(iter.cur.value, n.value) == 0 { + n = iter.cur + } else { + break + } + } + result[1] = n + n = nil + default: + panic("Get compare only is allowed in -1, 0, 1") + } + } - if n == nil { + switch lastc { + case 1: + + if result[1] != nil { + + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) + } else { + result[0] = last + result[2] = GetNext(last, 1) + } + + case -1: + + if result[1] != nil { + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) + } else { + result[2] = last + result[0] = GetPrev(last, 1) + } + + case 0: + + if result[1] == nil { return } - - lastc := 0 - switch c := avl.comparator(key, n.key); 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: - - 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") - } - + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) } + return } -func (avl *Tree) GetNode(key interface{}) (*Node, bool) { - for n := avl.root; n != nil; { - switch c := avl.comparator(key, n.key); c { +func (tree *Tree) GetNode(key interface{}) (*Node, bool) { + + for n := tree.root; n != nil; { + switch c := tree.compare(key, n.key); c { case -1: n = n.children[0] case 1: n = n.children[1] case 0: + iter := NewIterator(n) + iter.Prev() + for iter.Prev() { + if tree.compare(iter.cur.key, n.key) == 0 { + n = iter.cur + } else { + break + } + } return n, true default: - panic("Get comparator only is allowed in -1, 0, 1") + panic("Get compare only is allowed in -1, 0, 1") } } return nil, false } -func (avl *Tree) Put(key, value interface{}) { - avl.size++ +func (tree *Tree) Put(key, value interface{}) { + tree.size++ node := &Node{key: key, value: value} - if avl.size == 1 { - avl.root = node + if tree.size == 1 { + tree.root = node return } - cur := avl.root + cur := tree.root parent := cur.parent child := -1 @@ -230,73 +320,164 @@ func (avl *Tree) Put(key, value interface{}) { parent.children[child] = node node.parent = parent if node.parent.height == 0 { - avl.fixPutHeight(node.parent) + tree.fixPutHeight(node.parent) } return } parent = cur - c := avl.comparator(key, cur.key) + c := tree.compare(key, cur.key) child = (c + 2) / 2 cur = cur.children[child] } - } -func (avl *Tree) debugString() string { - if avl.size == 0 { - return "" +type TraversalMethod int + +const ( + // L = left R = right D = Value(dest) + _ TraversalMethod = iota + //DLR 先值 然后左递归 右递归 下面同理 + DLR + //LDR 先从左边有序访问到右边 从小到大 + LDR + // LRD 同理 + LRD + + // DRL 同理 + DRL + + // RDL 先从右边有序访问到左边 从大到小 + RDL + + // RLD 同理 + RLD +) + +// Traversal 遍历的方法 默认是LDR 从小到大 compare 为 l < r +func (tree *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...interface{}) { + if tree.root == nil { + return } - str := "AVLTree\n" - outputfordebug(avl.root, "", true, &str) - 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]) + method := LDR + if len(traversalMethod) != 0 { + method = traversalMethod[0].(TraversalMethod) } - traverasl(avl.root) - return -} -func (avl *Tree) TraversalDepth(leftright int) (result []interface{}) { - result = make([]interface{}, 0, avl.size) - if leftright < 0 { - var traverasl func(cur *Node) - traverasl = func(cur *Node) { + switch method { + case DLR: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { if cur == nil { - return + return true } - traverasl(cur.children[0]) - result = append(result, cur.value) - traverasl(cur.children[1]) + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true } - traverasl(avl.root) - } else { - var traverasl func(cur *Node) - traverasl = func(cur *Node) { + traverasl(tree.root) + case LDR: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { if cur == nil { - return + return true } - traverasl(cur.children[1]) - result = append(result, cur.value) - traverasl(cur.children[0]) + if !traverasl(cur.children[0]) { + return false + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true } - traverasl(avl.root) + traverasl(tree.root) + case LRD: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + if !every(cur.value) { + return false + } + return true + } + traverasl(tree.root) + case DRL: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true + } + traverasl(tree.root) + case RDL: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[1]) { + return false + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + return true + } + traverasl(tree.root) + case RLD: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[1]) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !every(cur.value) { + return false + } + return true + } + traverasl(tree.root) } - - return } -func (avl *Tree) lrrotate(cur *Node) { +func (tree *Tree) lrrotate(cur *Node) { const l = 1 const r = 0 @@ -331,12 +512,16 @@ func (avl *Tree) lrrotate(cur *Node) { cur.children[r] = mov mov.parent = cur + // movparent.size = getChildrenSumSize(movparent) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) rlrotate(cur *Node) { +func (tree *Tree) rlrotate(cur *Node) { const l = 0 const r = 1 @@ -369,30 +554,31 @@ func (avl *Tree) rlrotate(cur *Node) { cur.children[r] = mov mov.parent = cur + // movparent.size = getChildrenSumSize(movparent) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) rrotate(cur *Node) { +func (tree *Tree) rrotateex(cur *Node) { const l = 0 const r = 1 // 1 right 0 left mov := cur.children[l] - + if mov == nil { + return + } mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 - // if mov.children[l] != nil { - // mov.children[l].parent = cur - // cur.children[l] = mov.children[l] - // } else { - // cur.children[l] = nil - // } - - // 不可能为nil - mov.children[l].parent = cur + // mov.children[l]不可能为nil cur.children[l] = mov.children[l] + if mov.children[l] != nil { + mov.children[l].parent = cur + } // 解决mov节点孩子转移的问题 if mov.children[r] != nil { @@ -415,7 +601,83 @@ func (avl *Tree) rrotate(cur *Node) { cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) lrotate(cur *Node) { +func (tree *Tree) rrotate(cur *Node) { + + const l = 0 + const r = 1 + // 1 right 0 left + mov := cur.children[l] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + // mov.children[l]不可能为nil + mov.children[l].parent = cur + cur.children[l] = mov.children[l] + + // 解决mov节点孩子转移的问题 + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + } else { + mov.children[l] = nil + } + + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.children[r] = mov + + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + + mov.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + +func (tree *Tree) lrotateex(cur *Node) { + + const l = 1 + const r = 0 + + mov := cur.children[l] + if mov == nil { + return + } + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + // 不可能为nil + cur.children[l] = mov.children[l] + if mov.children[l] != nil { + mov.children[l].parent = cur + } + + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + } else { + mov.children[l] = nil + } + + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } + + cur.children[r] = mov + + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + + mov.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + +func (tree *Tree) lrotate(cur *Node) { const l = 1 const r = 0 @@ -424,13 +686,6 @@ func (avl *Tree) lrotate(cur *Node) { mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 - // if mov.children[l] != nil { - // mov.children[l].parent = cur - // cur.children[l] = mov.children[l] - // } else { - // cur.children[l] = nil - // } - // 不可能为nil mov.children[l].parent = cur cur.children[l] = mov.children[l] @@ -450,6 +705,9 @@ func (avl *Tree) lrotate(cur *Node) { cur.children[r] = mov + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } @@ -482,42 +740,35 @@ func getHeight(cur *Node) int { return cur.height } -func (avl *Tree) fixRemoveHeight(cur *Node) { - +func (tree *Tree) fixRemoveHeight(cur *Node) { for { lefth, rigthh, lrmax := getMaxAndChildrenHeight(cur) // 判断当前节点是否有变化, 如果没变化的时候, 不需要往上修复 - isBreak := false - if cur.height == lrmax+1 { - isBreak = true - } else { - cur.height = lrmax + 1 - } + curheight := lrmax + 1 + cur.height = curheight // 计算高度的差值 绝对值大于2的时候需要旋转 diff := lefth - rigthh if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } else if diff > 1 { l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { - - if isBreak { + if cur.height == curheight { return } - } if cur.parent == nil { @@ -529,7 +780,7 @@ func (avl *Tree) fixRemoveHeight(cur *Node) { } -func (avl *Tree) fixPutHeight(cur *Node) { +func (tree *Tree) fixPutHeight(cur *Node) { for { @@ -541,16 +792,16 @@ func (avl *Tree) fixPutHeight(cur *Node) { if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } else if diff > 1 { l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { @@ -587,7 +838,7 @@ func output(node *Node, prefix string, isTail bool, str *string) { *str += "┌── " } - *str += spew.Sprint(node.value) + "\n" + *str += spew.Sprint(node.key) + "\n" if node.children[0] != nil { newPrefix := prefix @@ -627,7 +878,7 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { parentv = spew.Sprint(node.parent.value) } suffix += parentv + "|" + spew.Sprint(node.height) + ")" - *str += spew.Sprint(node.value) + suffix + "\n" + *str += spew.Sprint(node.key) + suffix + "\n" if node.children[0] != nil { newPrefix := prefix @@ -639,3 +890,12 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { outputfordebug(node.children[0], newPrefix, true, str) } } + +func (tree *Tree) debugString() string { + if tree.size == 0 { + return "" + } + str := "AVLTree\n" + outputfordebug(tree.root, "", true, &str) + return str +} diff --git a/avlkey/avlkey_test.go b/avlkey/avlkey_test.go index 041c576..8581387 100644 --- a/avlkey/avlkey_test.go +++ b/avlkey/avlkey_test.go @@ -8,18 +8,18 @@ import ( "os" "testing" + "474420502.top/eson/structure/compare" "github.com/Pallinder/go-randomdata" "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/trees/avltree" "github.com/emirpasic/gods/trees/redblacktree" - "github.com/emirpasic/gods/utils" ) -const CompartorSize = 500000 -const NumberMax = 60000000 +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 { @@ -29,13 +29,13 @@ func TestSave(t *testing.T) { //fmt.Println(userBytes) var l []int - m := make(map[int]int) + // m := make(map[int]int) for i := 0; len(l) < CompartorSize; i++ { v := randomdata.Number(0, NumberMax) - if _, ok := m[v]; !ok { - m[v] = v - l = append(l, v) - } + // if _, ok := m[v]; !ok { + // m[v] = v + l = append(l, v) + // } } var result bytes.Buffer @@ -58,10 +58,10 @@ func loadTestData() []int { } func TestIterator(t *testing.T) { - avl := New(utils.IntComparator) + tree := 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, v) + tree.Put(v, v) } // ` AVLTree @@ -79,78 +79,195 @@ func TestIterator(t *testing.T) { // └── 2 // └── 1` - iter := avl.Iterator() // root start point - + iter := tree.Iterator() // root start point l := []int{14, 15, 20, 21, 30} - for i := 0; iter.Prev(); i++ { + for i := 0; iter.Next(); i++ { if iter.Value().(int) != l[i] { - t.Error("iter prev error", iter.Value(), l[i]) + t.Error("iter Next error", iter.Value(), l[i]) } } - iter.Prev() + iter.Next() if iter.Value().(int) != 30 { - t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value()) + t.Error("Next == false", iter.Value(), iter.Next(), 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 + for i := 0; iter.Prev(); 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.Prev() != false { + t.Error("Prev is error, cur is tail, val = 1 Prev return false") } if iter.Value().(int) != 1 { // cur is 1 - t.Error("next == false", iter.Value(), iter.Next(), iter.Value()) + t.Error("next == false", iter.Value(), iter.Prev(), iter.Value()) } - if iter.Prev() != true && iter.Value().(int) != 2 { + if iter.Next() != true && iter.Value().(int) != 2 { t.Error("next to prev is error") } } +func TestGetRange(t *testing.T) { + tree := New(compare.Int) + for _, v := range []int{5, 6, 8, 10, 13, 17, 1, 2, 40, 30} { + tree.Put(v, 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 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, v) + tree := New(compare.Int) + for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} { + tree.Put(v, v) } - if spew.Sprint(avl.GetAround(30)) != "[40 30 21]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(30))) + var Result string + + Result = spew.Sprint(tree.GetAround(14)) + if Result != "[7 14 14]" { + t.Error(tree.Values()) + t.Error("14 is root, tree.GetAround(14)) is error", Result) + t.Error(tree.debugString()) } - if spew.Sprint(avl.GetAround(40)) != "[40 40 30]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50))) + Result = spew.Sprint(tree.GetAround(17)) + if Result != "[16 17 20]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(17)) is error", Result) + t.Error(tree.debugString()) } - if spew.Sprint(avl.GetAround(50)) != "[ 50 40]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50))) + Result = spew.Sprint(tree.GetAround(3)) + if Result != "[ 3 7]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(3)) is error", Result) + t.Error(tree.debugString()) } + + 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 ]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(50)) is error", Result) + t.Error(tree.debugString()) + } + + Result = spew.Sprint(tree.GetAround(18)) + if Result != "[17 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 7]" { + 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 != "[ 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 ]" { + 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 func TestPutStable(t *testing.T) { - // avl := New(utils.IntComparator) - // gods := avltree.NewWithIntComparator() - // // 44908, 34985, 62991, 4201, 27210, 30707 - // for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - // t.Error(v) - // t.Error(avl.debugString()) - // avl.Put(v, v) - // gods.Put(v, v) - // t.Error(avl.debugString()) - // t.Error(gods.String()) - // } + f, _ := os.OpenFile("./test.log", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666) + log.SetOutput(f) + // 0-1 3 | 2-3 7-8 | 4-7 12-16 | 8-15 20-32 | 16-31 33-58 l := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 19, 20, 21, 22, 30, 41, 41, 41} + + for i := 0; i < 100000; i++ { + var l []int + for len(l) < 1000 { + l = append(l, randomdata.Number(0, 100)) + } + + tree := New(compare.Int) + for _, v := range l { + tree.Put(v, v) + } + } + + // t.Error(avl.debugString(), avl.TraversalBreadth(), "\n", "-----------") + } func TestPutComparatorRandom(t *testing.T) { for n := 0; n < 300000; n++ { - avl := New(utils.IntComparator) + tree := New(utils.IntComparator) godsavl := avltree.NewWithIntComparator() content := "" @@ -160,16 +277,14 @@ func TestPutComparatorRandom(t *testing.T) { if _, ok := m[v]; !ok { m[v] = v content += spew.Sprint(v) + "," - // t.Error(v) - avl.Put(v, v) - // t.Error(avl.String()) + tree.Put(v, v) godsavl.Put(v, v) } } - if avl.String() != godsavl.String() { + if tree.String() != godsavl.String() { t.Error(godsavl.String()) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(content, n) break } @@ -177,9 +292,9 @@ func TestPutComparatorRandom(t *testing.T) { } func TestGet(t *testing.T) { - avl := New(utils.IntComparator) + tree := New(utils.IntComparator) for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - avl.Put(v, v) + tree.Put(v, v) } result := ` @@ -195,20 +310,20 @@ func TestGet(t *testing.T) { └── 1562 ` - s1 := avl.String() + s1 := tree.String() s2 := "AVLTree" + result if s1 != s2 { t.Error(s1, s2) } for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - v, ok := avl.Get(v) + v, ok := tree.Get(v) if !ok { t.Error("the val not found ", v) } } - if v, ok := avl.Get(10000); ok { + if v, ok := tree.Get(10000); ok { t.Error("the val(1000) is not in tree, but is found", v) } @@ -218,7 +333,7 @@ func TestRemoveAll(t *testing.T) { ALL: for c := 0; c < 5000; c++ { - avl := New(utils.IntComparator) + tree := New(utils.IntComparator) gods := avltree.NewWithIntComparator() var l []int m := make(map[int]int) @@ -228,31 +343,32 @@ ALL: if _, ok := m[v]; !ok { m[v] = v l = append(l, v) - avl.Put(v, v) + tree.Put(v, v) gods.Put(v, v) } } for i := 0; i < 100; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - s1 := spew.Sprint(avl.TraversalDepth(-1)) + s1 := spew.Sprint(tree.Values()) s2 := spew.Sprint(gods.Values()) if s1 != s2 { - t.Error("avl remove error", "avlsize = ", avl.Size()) + t.Error("avl remove error", "avlsize = ", tree.Size()) t.Error(s1) t.Error(s2) break ALL } } } + } func TestRemove(t *testing.T) { ALL: for N := 0; N < 500000; N++ { - avl := New(utils.IntComparator) + tree := New(utils.IntComparator) gods := avltree.NewWithIntComparator() var l []int @@ -263,22 +379,22 @@ ALL: if _, ok := m[v]; !ok { l = append(l, v) m[v] = v - avl.Put(v, v) + tree.Put(v, v) gods.Put(v, v) } } - src1 := avl.String() + src1 := tree.String() src2 := gods.String() for i := 0; i < 10; i++ { - avl.Remove(l[i]) + tree.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(tree.Values()) && tree.size != 0 { // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { t.Error(src1) t.Error(src2) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(gods.String()) t.Error(l[i]) // t.Error(avl.TraversalDepth(-1)) @@ -290,10 +406,9 @@ ALL: } func BenchmarkIterator(b *testing.B) { - tree := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() - b.N = len(l) for _, v := range l { tree.Put(v, v) @@ -301,39 +416,25 @@ func BenchmarkIterator(b *testing.B) { b.ResetTimer() b.StartTimer() + b.N = 0 iter := tree.Iterator() for iter.Next() { + b.N++ } for iter.Prev() { + b.N++ } 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() { + b.N++ } for iter.Prev() { + b.N++ } - for iter.Next() { - } + } func BenchmarkRemove(b *testing.B) { - tree := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() @@ -388,7 +489,7 @@ func BenchmarkGodsRBRemove(b *testing.B) { func BenchmarkGet(b *testing.B) { - avl := New(utils.IntComparator) + tree := New(utils.IntComparator) l := loadTestData() b.N = len(l) @@ -396,7 +497,7 @@ func BenchmarkGet(b *testing.B) { b.ResetTimer() b.StartTimer() for i := 0; i < b.N; i++ { - avl.Get(l[i]) + tree.Get(l[i]) } } @@ -427,18 +528,21 @@ func BenchmarkGodsAvlGet(b *testing.B) { } func BenchmarkPut(b *testing.B) { - avl := New(utils.IntComparator) l := loadTestData() b.ResetTimer() b.StartTimer() - b.N = len(l) - for _, v := range l { - avl.Put(v, v) + execCount := 50 + b.N = len(l) * execCount + for i := 0; i < execCount; i++ { + tree := New(utils.IntComparator) + for _, v := range l { + tree.Put(v, v) + } } - + // b.Log(avl.count) } func BenchmarkGodsRBPut(b *testing.B) { diff --git a/avlkey/iterator.go b/avlkey/iterator.go index 3067284..b8173b2 100644 --- a/avlkey/iterator.go +++ b/avlkey/iterator.go @@ -5,8 +5,6 @@ import ( ) type Iterator struct { - op *Tree - dir int up *Node cur *Node @@ -15,11 +13,17 @@ 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(n *Node) *Iterator { + iter := &Iterator{tstack: lastack.New()} + iter.up = n + return iter +} + func (iter *Iterator) Value() interface{} { return iter.cur.value } @@ -42,46 +46,47 @@ func (iter *Iterator) Right() bool { return false } -func (iter *Iterator) Prev() (result bool) { +func GetNext(cur *Node, idx int) *Node { - 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 := 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) } - iter.dir = -1 - } - if iter.tstack.Size() == 0 { - if iter.up == nil { - return false + 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 } - 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 + return cur } func (iter *Iterator) Next() (result bool) { - if iter.dir < 1 { // 非 1(next 方向定义 -1 为 prev) - if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 + if iter.dir > -1 { + if iter.dir == 1 && iter.cur != nil { iter.tstack.Clear() - iter.curPushNextStack(iter.cur) // 把当前cur计算的逆向回朔 - iter.up = iter.getNextUp(iter.cur) // cur 寻找下个要计算up + iter.curPushNextStack(iter.cur) + iter.up = iter.getNextUp(iter.cur) } - iter.dir = 1 + iter.dir = -1 } - // 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值 if iter.tstack.Size() == 0 { if iter.up == nil { return false @@ -96,6 +101,64 @@ func (iter *Iterator) Next() (result bool) { return true } + 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 { // 非 1(next 方向定义 -1 为 prev) + if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 + iter.tstack.Clear() + iter.curPushPrevStack(iter.cur) // 把当前cur计算的逆向回朔 + iter.up = iter.getPrevUp(iter.cur) // cur 寻找下个要计算up + } + iter.dir = 1 + } + + // 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值 + 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 + } + // 如果再次计算的栈为空, 则只能返回false return false } @@ -107,7 +170,7 @@ func getRelationship(cur *Node) int { return 0 } -func (iter *Iterator) getNextUp(cur *Node) *Node { +func (iter *Iterator) getPrevUp(cur *Node) *Node { for cur.parent != nil { if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序 return cur.parent @@ -117,19 +180,19 @@ func (iter *Iterator) getNextUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushNextStack(cur *Node) { - next := cur.children[0] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值 +func (iter *Iterator) curPushPrevStack(cur *Node) { + Prev := 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) // 入栈 用于回溯 + if Prev != nil { + iter.tstack.Push(Prev) + for Prev.children[1] != nil { + Prev = Prev.children[1] + iter.tstack.Push(Prev) // 入栈 用于回溯 } } } -func (iter *Iterator) getPrevUp(cur *Node) *Node { +func (iter *Iterator) getNextUp(cur *Node) *Node { for cur.parent != nil { if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序 return cur.parent @@ -139,14 +202,14 @@ func (iter *Iterator) getPrevUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushPrevStack(cur *Node) { - prev := cur.children[1] +func (iter *Iterator) curPushNextStack(cur *Node) { + next := cur.children[1] - if prev != nil { - iter.tstack.Push(prev) - for prev.children[0] != nil { - prev = prev.children[0] - iter.tstack.Push(prev) + if next != nil { + iter.tstack.Push(next) + for next.children[0] != nil { + next = next.children[0] + iter.tstack.Push(next) } } } diff --git a/avlkeydup/avlkeydup.go b/avlkeydup/avlkeydup.go index fe4677a..d886bce 100644 --- a/avlkeydup/avlkeydup.go +++ b/avlkeydup/avlkeydup.go @@ -1,9 +1,8 @@ package avlkeydup import ( + "474420502.top/eson/structure/compare" "github.com/davecgh/go-spew/spew" - - "github.com/emirpasic/gods/utils" ) type Node struct { @@ -13,13 +12,6 @@ type Node struct { key, value interface{} } -// func (n *Node) String() string { -// if n == nil { -// return "nil" -// } -// return spew.Sprint(n.value) -// } - func (n *Node) String() string { if n == nil { return "nil" @@ -33,40 +25,40 @@ func (n *Node) String() string { } type Tree struct { - root *Node - size int - comparator utils.Comparator + root *Node + size int + compare compare.Compare } -func New(comparator utils.Comparator) *Tree { - return &Tree{comparator: comparator} +func New(compare compare.Compare) *Tree { + return &Tree{compare: compare} } -func (avl *Tree) String() string { - if avl.size == 0 { +func (tree *Tree) String() string { + if tree.size == 0 { return "" } str := "AVLTree\n" - 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 { - return avl.size +func (tree *Tree) Size() int { + return tree.size } -func (avl *Tree) Remove(key interface{}) *Node { +func (tree *Tree) Remove(key interface{}) *Node { - if n, ok := avl.GetNode(key); ok { + if n, ok := tree.GetNode(key); ok { - avl.size-- - if avl.size == 0 { - avl.root = nil + tree.size-- + if tree.size == 0 { + tree.root = nil return n } @@ -76,7 +68,7 @@ func (avl *Tree) Remove(key interface{}) *Node { if left == -1 && right == -1 { p := n.parent p.children[getRelationship(n)] = nil - avl.fixRemoveHeight(p) + tree.fixRemoveHeight(p) return n } @@ -113,9 +105,9 @@ func (avl *Tree) Remove(key interface{}) *Node { // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 if cparent == n { - avl.fixRemoveHeight(n) + tree.fixRemoveHeight(n) } else { - avl.fixRemoveHeight(cparent) + tree.fixRemoveHeight(cparent) } return cur @@ -124,16 +116,94 @@ func (avl *Tree) Remove(key interface{}) *Node { return nil } -func (avl *Tree) Get(key interface{}) (interface{}, bool) { - n, ok := avl.GetNode(key) +// Values 返回先序遍历的值 +func (tree *Tree) Values() []interface{} { + mszie := 0 + if tree.root != nil { + mszie = tree.size + } + result := make([]interface{}, 0, mszie) + tree.Traversal(func(v interface{}) bool { + result = append(result, v) + return true + }, LDR) + return result +} + +func (tree *Tree) GetRange(k1, k2 interface{}) (result []interface{}) { + c := tree.compare(k2, k1) + switch c { + case 1: + + var min, max *Node + resultmin := tree.getArountNode(k1) + resultmax := tree.getArountNode(k2) + for i := 1; i < 3 && min == nil; 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.Next() { + result = append(result, iter.Value()) + if iter.cur == max { + break + } + } + case -1: + + var min, max *Node + resultmin := tree.getArountNode(k2) + resultmax := tree.getArountNode(k1) + 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.Prev() { + result = append(result, iter.Value()) + if iter.cur == min { + break + } + } + case 0: + if n, ok := tree.GetNode(k1); ok { + return []interface{}{n.value} + } + return []interface{}{} + } + + return +} + +func (tree *Tree) Get(key interface{}) (interface{}, bool) { + n, ok := tree.GetNode(key) if ok { return n.value, true } return n, false } -func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { - an := avl.GetAroundNode(key) +func (tree *Tree) GetAround(key interface{}) (result [3]interface{}) { + an := tree.getArountNode(key) for i, n := range an { if n != nil { result[i] = n.value @@ -142,170 +212,277 @@ func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { return } -func (avl *Tree) GetAroundNode(key interface{}) (result [3]*Node) { - n := avl.root +func (tree *Tree) getArountNode(key interface{}) (result [3]*Node) { + var last *Node + var lastc int - for { + for n := tree.root; n != nil; { + last = n + c := tree.compare(key, n.value) + switch c { + case -1: + n = n.children[0] + lastc = c + case 1: + n = n.children[1] + lastc = c + case 0: + iter := NewIterator(n) + iter.Prev() + for iter.Prev() { + if tree.compare(iter.cur.value, n.value) == 0 { + n = iter.cur + } else { + break + } + } + result[1] = n + n = nil + default: + panic("Get compare only is allowed in -1, 0, 1") + } + } - if n == nil { + switch lastc { + case 1: + + if result[1] != nil { + + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) + } else { + result[0] = last + result[2] = GetNext(last, 1) + } + + case -1: + + if result[1] != nil { + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) + } else { + result[2] = last + result[0] = GetPrev(last, 1) + } + + case 0: + + if result[1] == nil { return } - - lastc := 0 - switch c := avl.comparator(key, n.key); 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: - - 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") - } - + result[0] = GetPrev(result[1], 1) + result[2] = GetNext(result[1], 1) } + return } -func (avl *Tree) GetNode(key interface{}) (*Node, bool) { - for n := avl.root; n != nil; { - switch c := avl.comparator(key, n.key); c { +func (tree *Tree) GetNode(key interface{}) (*Node, bool) { + + for n := tree.root; n != nil; { + switch c := tree.compare(key, n.key); c { case -1: n = n.children[0] case 1: n = n.children[1] case 0: + iter := NewIterator(n) + iter.Prev() + for iter.Prev() { + if tree.compare(iter.cur.key, n.key) == 0 { + n = iter.cur + } else { + break + } + } return n, true default: - panic("Get comparator only is allowed in -1, 0, 1") + panic("Get compare only is allowed in -1, 0, 1") } } return nil, false } -func (avl *Tree) Put(key, value interface{}) { - - if avl.size == 0 { - avl.root = &Node{key: key, value: value} - avl.size++ +func (tree *Tree) Put(key, value interface{}) { + tree.size++ + node := &Node{key: key, value: value} + if tree.size == 1 { + tree.root = node return } - cur := avl.root + cur := tree.root parent := cur.parent child := -1 for { if cur == nil { - avl.size++ - node := &Node{key: key, value: value} parent.children[child] = node node.parent = parent if node.parent.height == 0 { - avl.fixPutHeight(node.parent) + tree.fixPutHeight(node.parent) } return } parent = cur - c := avl.comparator(key, cur.key) - + c := tree.compare(key, cur.key) if c == 0 { cur.key = key cur.value = value return } - child = (c + 2) / 2 cur = cur.children[child] } - } -func (avl *Tree) debugString() string { - if avl.size == 0 { - return "" +type TraversalMethod int + +const ( + // L = left R = right D = Value(dest) + _ TraversalMethod = iota + //DLR 先值 然后左递归 右递归 下面同理 + DLR + //LDR 先从左边有序访问到右边 从小到大 + LDR + // LRD 同理 + LRD + + // DRL 同理 + DRL + + // RDL 先从右边有序访问到左边 从大到小 + RDL + + // RLD 同理 + RLD +) + +// Traversal 遍历的方法 默认是LDR 从小到大 compare 为 l < r +func (tree *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...interface{}) { + if tree.root == nil { + return } - str := "AVLTree\n" - outputfordebug(avl.root, "", true, &str) - 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]) + method := LDR + if len(traversalMethod) != 0 { + method = traversalMethod[0].(TraversalMethod) } - traverasl(avl.root) - return -} -func (avl *Tree) TraversalDepth(leftright int) (result []interface{}) { - result = make([]interface{}, 0, avl.size) - if leftright < 0 { - var traverasl func(cur *Node) - traverasl = func(cur *Node) { + switch method { + case DLR: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { if cur == nil { - return + return true } - traverasl(cur.children[0]) - result = append(result, cur.value) - traverasl(cur.children[1]) + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true } - traverasl(avl.root) - } else { - var traverasl func(cur *Node) - traverasl = func(cur *Node) { + traverasl(tree.root) + case LDR: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { if cur == nil { - return + return true } - traverasl(cur.children[1]) - result = append(result, cur.value) - traverasl(cur.children[0]) + if !traverasl(cur.children[0]) { + return false + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true } - traverasl(avl.root) + traverasl(tree.root) + case LRD: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + if !every(cur.value) { + return false + } + return true + } + traverasl(tree.root) + case DRL: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !traverasl(cur.children[1]) { + return false + } + return true + } + traverasl(tree.root) + case RDL: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[1]) { + return false + } + if !every(cur.value) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + return true + } + traverasl(tree.root) + case RLD: + var traverasl func(cur *Node) bool + traverasl = func(cur *Node) bool { + if cur == nil { + return true + } + if !traverasl(cur.children[1]) { + return false + } + if !traverasl(cur.children[0]) { + return false + } + if !every(cur.value) { + return false + } + return true + } + traverasl(tree.root) } - - return } -func (avl *Tree) lrrotate(cur *Node) { +func (tree *Tree) lrrotate(cur *Node) { const l = 1 const r = 0 @@ -340,12 +517,16 @@ func (avl *Tree) lrrotate(cur *Node) { cur.children[r] = mov mov.parent = cur + // movparent.size = getChildrenSumSize(movparent) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) rlrotate(cur *Node) { +func (tree *Tree) rlrotate(cur *Node) { const l = 0 const r = 1 @@ -378,30 +559,31 @@ func (avl *Tree) rlrotate(cur *Node) { cur.children[r] = mov mov.parent = cur + // movparent.size = getChildrenSumSize(movparent) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) rrotate(cur *Node) { +func (tree *Tree) rrotateex(cur *Node) { const l = 0 const r = 1 // 1 right 0 left mov := cur.children[l] - + if mov == nil { + return + } mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 - // if mov.children[l] != nil { - // mov.children[l].parent = cur - // cur.children[l] = mov.children[l] - // } else { - // cur.children[l] = nil - // } - - // 不可能为nil - mov.children[l].parent = cur + // mov.children[l]不可能为nil cur.children[l] = mov.children[l] + if mov.children[l] != nil { + mov.children[l].parent = cur + } // 解决mov节点孩子转移的问题 if mov.children[r] != nil { @@ -424,7 +606,83 @@ func (avl *Tree) rrotate(cur *Node) { cur.height = getMaxChildrenHeight(cur) + 1 } -func (avl *Tree) lrotate(cur *Node) { +func (tree *Tree) rrotate(cur *Node) { + + const l = 0 + const r = 1 + // 1 right 0 left + mov := cur.children[l] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + // mov.children[l]不可能为nil + mov.children[l].parent = cur + cur.children[l] = mov.children[l] + + // 解决mov节点孩子转移的问题 + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + } else { + mov.children[l] = nil + } + + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.children[r] = mov + + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + + mov.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + +func (tree *Tree) lrotateex(cur *Node) { + + const l = 1 + const r = 0 + + mov := cur.children[l] + if mov == nil { + return + } + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + // 不可能为nil + cur.children[l] = mov.children[l] + if mov.children[l] != nil { + mov.children[l].parent = cur + } + + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + } else { + mov.children[l] = nil + } + + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } + + cur.children[r] = mov + + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + + mov.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + +func (tree *Tree) lrotate(cur *Node) { const l = 1 const r = 0 @@ -433,13 +691,6 @@ func (avl *Tree) lrotate(cur *Node) { mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 - // if mov.children[l] != nil { - // mov.children[l].parent = cur - // cur.children[l] = mov.children[l] - // } else { - // cur.children[l] = nil - // } - // 不可能为nil mov.children[l].parent = cur cur.children[l] = mov.children[l] @@ -459,6 +710,9 @@ func (avl *Tree) lrotate(cur *Node) { cur.children[r] = mov + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 + mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 } @@ -491,42 +745,35 @@ func getHeight(cur *Node) int { return cur.height } -func (avl *Tree) fixRemoveHeight(cur *Node) { - +func (tree *Tree) fixRemoveHeight(cur *Node) { for { lefth, rigthh, lrmax := getMaxAndChildrenHeight(cur) // 判断当前节点是否有变化, 如果没变化的时候, 不需要往上修复 - isBreak := false - if cur.height == lrmax+1 { - isBreak = true - } else { - cur.height = lrmax + 1 - } + curheight := lrmax + 1 + cur.height = curheight // 计算高度的差值 绝对值大于2的时候需要旋转 diff := lefth - rigthh if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } else if diff > 1 { l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { - - if isBreak { + if cur.height == curheight { return } - } if cur.parent == nil { @@ -538,7 +785,7 @@ func (avl *Tree) fixRemoveHeight(cur *Node) { } -func (avl *Tree) fixPutHeight(cur *Node) { +func (tree *Tree) fixPutHeight(cur *Node) { for { @@ -550,16 +797,16 @@ func (avl *Tree) fixPutHeight(cur *Node) { if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - avl.lrrotate(cur) + tree.lrrotate(cur) } else { - avl.lrotate(cur) + tree.lrotate(cur) } } else if diff > 1 { l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - avl.rlrotate(cur) + tree.rlrotate(cur) } else { - avl.rrotate(cur) + tree.rrotate(cur) } } else { @@ -596,7 +843,7 @@ func output(node *Node, prefix string, isTail bool, str *string) { *str += "┌── " } - *str += spew.Sprint(node.value) + "\n" + *str += spew.Sprint(node.key) + "\n" if node.children[0] != nil { newPrefix := prefix @@ -636,7 +883,7 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { parentv = spew.Sprint(node.parent.value) } suffix += parentv + "|" + spew.Sprint(node.height) + ")" - *str += spew.Sprint(node.value) + suffix + "\n" + *str += spew.Sprint(node.key) + suffix + "\n" if node.children[0] != nil { newPrefix := prefix @@ -648,3 +895,12 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { outputfordebug(node.children[0], newPrefix, true, str) } } + +func (tree *Tree) debugString() string { + if tree.size == 0 { + return "" + } + str := "AVLTree\n" + outputfordebug(tree.root, "", true, &str) + return str +} diff --git a/avlkeydup/avlkeydup_test.go b/avlkeydup/avlkeydup_test.go index c418fa4..b76a5ab 100644 --- a/avlkeydup/avlkeydup_test.go +++ b/avlkeydup/avlkeydup_test.go @@ -5,9 +5,9 @@ import ( "encoding/gob" "io/ioutil" "log" - "os" "testing" + "474420502.top/eson/structure/compare" "github.com/Pallinder/go-randomdata" "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/trees/avltree" @@ -16,36 +16,6 @@ import ( "github.com/emirpasic/gods/utils" ) -const CompartorSize = 500000 -const NumberMax = 60000000 - -func TestSave(t *testing.T) { - - f, err := os.OpenFile("../l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) - if err != nil { - log.Println(err) - } - - //fmt.Println(userBytes) - - var l []int - m := make(map[int]int) - for i := 0; len(l) < CompartorSize; i++ { - v := randomdata.Number(0, NumberMax) - if _, ok := m[v]; !ok { - m[v] = v - l = append(l, v) - } - } - - var result bytes.Buffer - encoder := gob.NewEncoder(&result) - encoder.Encode(l) - lbytes := result.Bytes() - f.Write(lbytes) - -} - func loadTestData() []int { data, err := ioutil.ReadFile("../l.log") if err != nil { @@ -57,125 +27,145 @@ func loadTestData() []int { return l } -func TestDupKey(t *testing.T) { - tree1 := New(utils.IntComparator) - tree2 := avltree.NewWithIntComparator() - - for i := 0; i < CompartorSize/100; i++ { - v := randomdata.Number(0, NumberMax) - tree1.Put(v, v) - tree2.Put(v, v) +func TestGetRange(t *testing.T) { + tree := New(compare.Int) + for _, v := range []int{5, 6, 8, 10, 13, 17, 1, 2, 40, 30} { + tree.Put(v, v) } - tree1.Put(500, 500) - tree2.Put(500, 500) + // t.Error(tree.debugString()) + // t.Error(tree.getArountNode(20)) + // t.Error(tree.Values()) - tree1.Put(500, 500) - tree2.Put(500, 500) - - if tree1.Size() != tree2.Size() { - t.Error("tree size is not equal") + result := tree.GetRange(0, 20) + if spew.Sprint(result) != "[1 2 5 6 8 10 13 17]" { + t.Error(result) } - if tree1.String() != tree2.String() { - t.Error(tree1.String()) - } -} - -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, v) - - } - // ` AVLTree - // │ ┌── 30 - // │ │ └── 21 - // │ ┌── 20 - // │ │ └── 15 - // └── 14 - // │ ┌── 7 - // │ ┌── 7 - // │ │ └── 6 - // └── 5 - // │ ┌── 4 - // │ │ └── 3 - // └── 2 - // └── 1` - - iter := avl.Iterator() // root start point - - l := []int{14, 15, 20, 21, 30} - - for i := 0; iter.Prev(); i++ { - if iter.Value().(int) != l[i] { - t.Error("iter prev error", iter.Value(), l[i]) - } + result = tree.GetRange(-5, -1) + if spew.Sprint(result) != "[]" { + t.Error(result) } - iter.Prev() - if iter.Value().(int) != 30 { - t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value()) + result = tree.GetRange(7, 20) + if spew.Sprint(result) != "[8 10 13 17]" { + t.Error(result) } - 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()) - } + result = tree.GetRange(30, 40) + if spew.Sprint(result) != "[30 40]" { + t.Error(result) } - 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()) + result = tree.GetRange(30, 60) + if spew.Sprint(result) != "[30 40]" { + t.Error(result) } - if iter.Prev() != true && iter.Value().(int) != 2 { - t.Error("next to prev is error") + 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 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, v) + tree := New(compare.Int) + for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} { + tree.Put(v, v) } - if spew.Sprint(avl.GetAround(30)) != "[40 30 21]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(30))) + var Result string + + Result = spew.Sprint(tree.GetAround(14)) + if Result != "[7 14 15]" { + t.Error(tree.Values()) + t.Error("17 is root, tree.GetAround(14)) is error", Result) + t.Error(tree.debugString()) } - if spew.Sprint(avl.GetAround(40)) != "[40 40 30]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50))) + Result = spew.Sprint(tree.GetAround(17)) + if Result != "[16 17 20]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(17)) is error", Result) + t.Error(tree.debugString()) } - if spew.Sprint(avl.GetAround(50)) != "[ 50 40]" { - t.Error("avl.GetAround(40)) is error", spew.Sprint(avl.GetAround(50))) + Result = spew.Sprint(tree.GetAround(3)) + if Result != "[ 3 7]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(3)) is error", Result) + t.Error(tree.debugString()) } + + Result = spew.Sprint(tree.GetAround(40)) + if Result != "[30 40 50]" { + 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 ]" { + t.Error(tree.Values()) + t.Error("tree.GetAround(50)) is error", Result) + t.Error(tree.debugString()) + } + + Result = spew.Sprint(tree.GetAround(18)) + if Result != "[17 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 7]" { + 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 != "[ 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 ]" { + 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 func TestPutStable(t *testing.T) { - // avl := New(utils.IntComparator) - // gods := avltree.NewWithIntComparator() - // // 44908, 34985, 62991, 4201, 27210, 30707 - // for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - // t.Error(v) - // t.Error(avl.debugString()) - // avl.Put(v, v) - // gods.Put(v, v) - // t.Error(avl.debugString()) - // t.Error(gods.String()) - // } + // t.Error(tree.debugString(), tree.TraversalBreadth(), "\n", "-----------") } func TestPutComparatorRandom(t *testing.T) { for n := 0; n < 300000; n++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) godsavl := avltree.NewWithIntComparator() content := "" @@ -185,16 +175,14 @@ func TestPutComparatorRandom(t *testing.T) { if _, ok := m[v]; !ok { m[v] = v content += spew.Sprint(v) + "," - // t.Error(v) - avl.Put(v, v) - // t.Error(avl.String()) + tree.Put(v, v) godsavl.Put(v, v) } } - if avl.String() != godsavl.String() { + if tree.String() != godsavl.String() { t.Error(godsavl.String()) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(content, n) break } @@ -202,9 +190,9 @@ func TestPutComparatorRandom(t *testing.T) { } func TestGet(t *testing.T) { - avl := New(utils.IntComparator) + tree := New(compare.Int) for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - avl.Put(v, v) + tree.Put(v, v) } result := ` @@ -220,21 +208,21 @@ func TestGet(t *testing.T) { └── 1562 ` - s1 := avl.String() + s1 := tree.String() s2 := "AVLTree" + result if s1 != s2 { t.Error(s1, s2) } for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - v, ok := avl.Get(v) + v, ok := tree.Get(v) if !ok { t.Error("the val not found ", v) } } - if v, ok := avl.Get(10000); ok { - t.Error("the val(1000) is not in tree, but is found", v) + if v, ok := tree.Get(10000); ok { + t.Error("the val(10000) is not in tree, but is found", v) } } @@ -243,7 +231,7 @@ func TestRemoveAll(t *testing.T) { ALL: for c := 0; c < 5000; c++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) gods := avltree.NewWithIntComparator() var l []int m := make(map[int]int) @@ -253,31 +241,32 @@ ALL: if _, ok := m[v]; !ok { m[v] = v l = append(l, v) - avl.Put(v, v) + tree.Put(v, v) gods.Put(v, v) } } for i := 0; i < 100; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - s1 := spew.Sprint(avl.TraversalDepth(-1)) + s1 := spew.Sprint(tree.Values()) s2 := spew.Sprint(gods.Values()) if s1 != s2 { - t.Error("avl remove error", "avlsize = ", avl.Size()) + t.Error("avl remove error", "avlsize = ", tree.Size()) t.Error(s1) t.Error(s2) break ALL } } } + } func TestRemove(t *testing.T) { ALL: for N := 0; N < 500000; N++ { - avl := New(utils.IntComparator) + tree := New(compare.Int) gods := avltree.NewWithIntComparator() var l []int @@ -288,25 +277,25 @@ ALL: if _, ok := m[v]; !ok { l = append(l, v) m[v] = v - avl.Put(v, v) + tree.Put(v, v) gods.Put(v, v) } } - src1 := avl.String() + src1 := tree.String() src2 := gods.String() for i := 0; i < 10; i++ { - avl.Remove(l[i]) + tree.Remove(l[i]) gods.Remove(l[i]) - if spew.Sprint(gods.Values()) != spew.Sprint(avl.TraversalDepth(-1)) && avl.size != 0 { - // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { + if spew.Sprint(gods.Values()) != spew.Sprint(tree.Values()) && tree.size != 0 { + // if gods.String() != tree.String() && gods.Size() != 0 && tree.size != 0 { t.Error(src1) t.Error(src2) - t.Error(avl.debugString()) + t.Error(tree.debugString()) t.Error(gods.String()) t.Error(l[i]) - // t.Error(avl.TraversalDepth(-1)) + // t.Error(tree.TraversalDepth(-1)) // t.Error(gods.Values()) break ALL } @@ -318,7 +307,6 @@ func BenchmarkIterator(b *testing.B) { tree := New(utils.IntComparator) l := loadTestData() - b.N = len(l) for _, v := range l { tree.Put(v, v) @@ -326,35 +314,21 @@ func BenchmarkIterator(b *testing.B) { b.ResetTimer() b.StartTimer() + b.N = 0 iter := tree.Iterator() for iter.Next() { + b.N++ } for iter.Prev() { + b.N++ } 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() { + b.N++ } for iter.Prev() { + b.N++ } - for iter.Next() { - } + } func BenchmarkRemove(b *testing.B) { @@ -362,15 +336,16 @@ func BenchmarkRemove(b *testing.B) { l := loadTestData() - b.N = len(l) for _, v := range l { tree.Put(v, v) } + ll := tree.Values() + b.N = len(ll) b.ResetTimer() b.StartTimer() - for i := 0; i < len(l); i++ { + for i := 0; i < len(ll); i++ { tree.Remove(l[i]) } } @@ -385,10 +360,12 @@ func BenchmarkGodsRemove(b *testing.B) { tree.Put(v, v) } + ll := tree.Values() + b.N = len(ll) b.ResetTimer() b.StartTimer() - for i := 0; i < len(l); i++ { + for i := 0; i < len(ll); i++ { tree.Remove(l[i]) } } @@ -403,17 +380,20 @@ func BenchmarkGodsRBRemove(b *testing.B) { tree.Put(v, v) } + ll := tree.Values() + b.N = len(ll) + b.ResetTimer() b.StartTimer() - for i := 0; i < len(l); i++ { + for i := 0; i < len(ll); i++ { tree.Remove(l[i]) } } func BenchmarkGet(b *testing.B) { - avl := New(utils.IntComparator) + tree := New(compare.Int) l := loadTestData() b.N = len(l) @@ -421,7 +401,7 @@ func BenchmarkGet(b *testing.B) { b.ResetTimer() b.StartTimer() for i := 0; i < b.N; i++ { - avl.Get(l[i]) + tree.Get(l[i]) } } @@ -452,18 +432,21 @@ func BenchmarkGodsAvlGet(b *testing.B) { } func BenchmarkPut(b *testing.B) { - avl := New(utils.IntComparator) l := loadTestData() b.ResetTimer() b.StartTimer() - b.N = len(l) - for _, v := range l { - avl.Put(v, v) + execCount := 50 + b.N = len(l) * execCount + for i := 0; i < execCount; i++ { + tree := New(compare.Int) + for _, v := range l { + tree.Put(v, v) + } } - + // b.Log(tree.count) } func BenchmarkGodsRBPut(b *testing.B) { diff --git a/avlkeydup/iterator.go b/avlkeydup/iterator.go index c8e325b..ac617a1 100644 --- a/avlkeydup/iterator.go +++ b/avlkeydup/iterator.go @@ -5,8 +5,6 @@ import ( ) type Iterator struct { - op *Tree - dir int up *Node cur *Node @@ -15,11 +13,17 @@ 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(n *Node) *Iterator { + iter := &Iterator{tstack: lastack.New()} + iter.up = n + return iter +} + func (iter *Iterator) Value() interface{} { return iter.cur.value } @@ -42,46 +46,47 @@ func (iter *Iterator) Right() bool { return false } -func (iter *Iterator) Prev() (result bool) { +func GetNext(cur *Node, idx int) *Node { - 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 := 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) } - iter.dir = -1 - } - if iter.tstack.Size() == 0 { - if iter.up == nil { - return false + 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 } - 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 + return cur } func (iter *Iterator) Next() (result bool) { - if iter.dir < 1 { // 非 1(next 方向定义 -1 为 prev) - if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 + if iter.dir > -1 { + if iter.dir == 1 && iter.cur != nil { iter.tstack.Clear() - iter.curPushNextStack(iter.cur) // 把当前cur计算的逆向回朔 - iter.up = iter.getNextUp(iter.cur) // cur 寻找下个要计算up + iter.curPushNextStack(iter.cur) + iter.up = iter.getNextUp(iter.cur) } - iter.dir = 1 + iter.dir = -1 } - // 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值 if iter.tstack.Size() == 0 { if iter.up == nil { return false @@ -96,6 +101,64 @@ func (iter *Iterator) Next() (result bool) { return true } + 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 { // 非 1(next 方向定义 -1 为 prev) + if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 + iter.tstack.Clear() + iter.curPushPrevStack(iter.cur) // 把当前cur计算的逆向回朔 + iter.up = iter.getPrevUp(iter.cur) // cur 寻找下个要计算up + } + iter.dir = 1 + } + + // 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值 + 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 + } + // 如果再次计算的栈为空, 则只能返回false return false } @@ -107,7 +170,7 @@ func getRelationship(cur *Node) int { return 0 } -func (iter *Iterator) getNextUp(cur *Node) *Node { +func (iter *Iterator) getPrevUp(cur *Node) *Node { for cur.parent != nil { if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序 return cur.parent @@ -117,19 +180,19 @@ func (iter *Iterator) getNextUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushNextStack(cur *Node) { - next := cur.children[0] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值 +func (iter *Iterator) curPushPrevStack(cur *Node) { + Prev := 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) // 入栈 用于回溯 + if Prev != nil { + iter.tstack.Push(Prev) + for Prev.children[1] != nil { + Prev = Prev.children[1] + iter.tstack.Push(Prev) // 入栈 用于回溯 } } } -func (iter *Iterator) getPrevUp(cur *Node) *Node { +func (iter *Iterator) getNextUp(cur *Node) *Node { for cur.parent != nil { if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序 return cur.parent @@ -139,14 +202,14 @@ func (iter *Iterator) getPrevUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushPrevStack(cur *Node) { - prev := cur.children[1] +func (iter *Iterator) curPushNextStack(cur *Node) { + next := cur.children[1] - if prev != nil { - iter.tstack.Push(prev) - for prev.children[0] != nil { - prev = prev.children[0] - iter.tstack.Push(prev) + if next != nil { + iter.tstack.Push(next) + for next.children[0] != nil { + next = next.children[0] + iter.tstack.Push(next) } } } diff --git a/for_test.go b/for_test.go index a8c001c..388c1e8 100644 --- a/for_test.go +++ b/for_test.go @@ -11,7 +11,7 @@ import ( randomdata "github.com/Pallinder/go-randomdata" ) -const CompartorSize = 100 +const CompartorSize = 1000000 const NumberMax = 50000000 func TestSave(t *testing.T) { diff --git a/vbtkey/vbtkey_test.go b/vbtkey/vbtkey_test.go index 29f39b9..1beda66 100644 --- a/vbtkey/vbtkey_test.go +++ b/vbtkey/vbtkey_test.go @@ -612,7 +612,7 @@ func BenchmarkPut(b *testing.B) { b.ResetTimer() b.StartTimer() - execCount := 10 + execCount := 50 b.N = len(l) * execCount for i := 0; i < execCount; i++ { tree := New(compare.Int) @@ -624,118 +624,6 @@ func BenchmarkPut(b *testing.B) { func TestPutStable(t *testing.T) { - // l := []int{14, 18, 20, 21, 22, 23, 19} - // 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)) - // } - - // tree := New(compare.Int) - // for _, v := range l { - // tree.Put(v, v) - // } - // result := tree.getArountNode(60) - - // if result[2] == nil && tree.indexNode(-1) != result[1] { - // t.Error(tree.debugString()) - // t.Error(tree.Values()) - // t.Error(result) - // } - - // result = tree.getArountNode(5) - // if result[0] == nil && tree.indexNode(0) != result[1] { - // t.Error(tree.debugString()) - // t.Error(tree.Values()) - // t.Error(result) - // } - - // result = tree.getArountNode(2) - // if result[2] == nil && tree.indexNode(0) != result[2] { - // t.Error(tree.debugString()) - // t.Error(tree.Values()) - // t.Error(result) - // } - - // result = tree.getArountNode(70) - // if result[0] == nil && tree.indexNode(-1) != result[0] { - // t.Error(tree.debugString()) - // t.Error(tree.Values()) - // t.Error(result) - // } - - // } - // for _, v := range []int{10, 0, 9, 5, -11, -10, -1, -5} { - // t.Error(tree.Index(v)) - // // t.Error(tree.debugString()) - // } - - // tree.RemoveIndex(4) - // t.Error(tree.Index(4)) - // t.Error(tree.Values()) - // t.Error(tree.debugString()) - // t.Error(len(l), tree.debugString(), "\n", "-----------") // 3 6(4) - -} - -func BenchmarkIndex(b *testing.B) { - tree := New(compare.Int) - - l := loadTestData() - b.N = len(l) - for i := 0; i < b.N; i++ { - tree.Put(l[i], i) - } - - b.ResetTimer() - b.StartTimer() - - b.N = 1000000 - - var result [50]interface{} - for n := 0; n < b.N; n++ { - i := 0 - tree.Traversal(func(v interface{}) bool { - result[i] = v - i++ - if i < 50 { - return true - } - log.Print(i) - return false - }) - } -} - -func BenchmarkTraversal(b *testing.B) { - tree := New(compare.Int) - - l := loadTestData() - b.N = len(l) - for i := 0; i < b.N; i++ { - tree.Put(l[i], i) - } - - b.ResetTimer() - b.StartTimer() - - execCount := 10 - b.N = len(l) * execCount - - for n := 0; n < execCount; n++ { - i := 0 - var result []interface{} - tree.Traversal(func(v interface{}) bool { - result = append(result, v) - i++ - if i >= 50 { - return false - } - return true - }) - - } } func BenchmarkGodsRBPut(b *testing.B) {