From 3e16572b121ecb7e0f47dda8f8b524445d1460d5 Mon Sep 17 00:00:00 2001 From: huangsimin Date: Fri, 15 Mar 2019 19:57:25 +0800 Subject: [PATCH] index tree is finish put --- avl/avl.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ avl/avl_test.go | 29 ++++++++++-------- avl/iterator.go | 4 +++ 3 files changed, 99 insertions(+), 12 deletions(-) diff --git a/avl/avl.go b/avl/avl.go index 3422c11..6c80bc2 100644 --- a/avl/avl.go +++ b/avl/avl.go @@ -125,6 +125,10 @@ func (avl *Tree) Get(key interface{}) (interface{}, bool) { return n, false } +func (avl *Tree) GetRange(min, max interface{}) []interface{} { + return nil +} + func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { an := avl.GetAroundNode(key) for i, n := range an { @@ -366,6 +370,44 @@ func (avl *Tree) rlrotate(cur *Node) { cur.height = getMaxChildrenHeight(cur) + 1 } +func (avl *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 //交换值达到, 相对位移 + + // 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 { + 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.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + func (avl *Tree) rrotate(cur *Node) { const l = 0 @@ -400,6 +442,42 @@ func (avl *Tree) rrotate(cur *Node) { cur.height = getMaxChildrenHeight(cur) + 1 } +func (avl *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.height = getMaxChildrenHeight(mov) + 1 + cur.height = getMaxChildrenHeight(cur) + 1 +} + func (avl *Tree) lrotate(cur *Node) { const l = 1 diff --git a/avl/avl_test.go b/avl/avl_test.go index 7d6013b..3d76c9e 100644 --- a/avl/avl_test.go +++ b/avl/avl_test.go @@ -16,7 +16,7 @@ import ( "github.com/emirpasic/gods/utils" ) -const CompartorSize = 500000 +const CompartorSize = 1000000 const NumberMax = 60000000 func TestSave(t *testing.T) { @@ -134,17 +134,22 @@ func TestGetAround(t *testing.T) { // 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()) - // } + + 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 range l { + avl := New(utils.IntComparator) + for _, v := range l { + avl.Put(v) + } + + for i := 0; i < 10; i++ { + r := randomdata.Number(0, len(l)) + t.Error(avl.String(), avl.TraversalBreadth()) + n, _ := avl.GetNode(l[r]) + avl.lrotateex(n) + } + t.Error(avl.String(), avl.TraversalBreadth(), "\n", "-----------") + } } func TestPutComparatorRandom(t *testing.T) { diff --git a/avl/iterator.go b/avl/iterator.go index 3ca4567..1236404 100644 --- a/avl/iterator.go +++ b/avl/iterator.go @@ -20,6 +20,10 @@ func initIterator(avltree *Tree) *Iterator { return iter } +func NewIterator(tree *Tree) *Iterator { + return initIterator(tree) +} + func (iter *Iterator) Value() interface{} { return iter.cur.value }