diff --git a/TODO b/TODO index e58892a..69fbaed 100644 --- a/TODO +++ b/TODO @@ -1 +1 @@ -add iterator test every file +旋转的size数值计算错误 \ No newline at end of file diff --git a/tree/lsv/iterator.go b/tree/lsv/diterator.go similarity index 85% rename from tree/lsv/iterator.go rename to tree/lsv/diterator.go index f39682f..9415429 100644 --- a/tree/lsv/iterator.go +++ b/tree/lsv/diterator.go @@ -6,31 +6,31 @@ import ( type Iterator struct { dir int - up *Node - cur *Node + up *DNode + cur *DNode tstack *lastack.Stack // curnext *Node } -func initIterator(avltree *Tree) *Iterator { +func initIterator(avltree *DTree) *Iterator { iter := &Iterator{tstack: lastack.New()} iter.up = avltree.root return iter } -func NewIterator(n *Node) *Iterator { +func NewIterator(n *DNode) *Iterator { iter := &Iterator{tstack: lastack.New()} iter.up = n return iter } -func NewIteratorWithCap(n *Node, cap int) *Iterator { +func NewIteratorWithCap(n *DNode, cap int) *Iterator { iter := &Iterator{tstack: lastack.NewWithCap(cap)} iter.up = n return iter } -func (iter *Iterator) GetNode() *Node { +func (iter *Iterator) GetNode() *DNode { return iter.cur } @@ -67,7 +67,7 @@ func (iter *Iterator) ToTail() { iter.cur = nil } -func (iter *Iterator) SetNode(n *Node) { +func (iter *Iterator) SetNode(n *DNode) { iter.up = n iter.dir = 0 iter.tstack.Clear() @@ -81,7 +81,7 @@ func (iter *Iterator) Value() interface{} { return iter.cur.value } -func (iter *Iterator) GetNext(cur *Node, idx int) *Node { +func (iter *Iterator) GetNext(cur *DNode, idx int) *DNode { // iter := NewIterator(cur) iter.SetNode(cur) @@ -99,7 +99,7 @@ func (iter *Iterator) GetNext(cur *Node, idx int) *Node { } if v, ok := iter.tstack.Pop(); ok { - iter.cur = v.(*Node) + iter.cur = v.(*DNode) if i == idx-1 { return iter.cur } @@ -132,14 +132,14 @@ func (iter *Iterator) Next() (result bool) { } if v, ok := iter.tstack.Pop(); ok { - iter.cur = v.(*Node) + iter.cur = v.(*DNode) iter.curPushNextStack(iter.cur) return true } return false } -func (iter *Iterator) GetPrev(cur *Node, idx int) *Node { +func (iter *Iterator) GetPrev(cur *DNode, idx int) *DNode { // iter := NewIterator(cur) iter.SetNode(cur) @@ -157,7 +157,7 @@ func (iter *Iterator) GetPrev(cur *Node, idx int) *Node { } if v, ok := iter.tstack.Pop(); ok { - iter.cur = v.(*Node) + iter.cur = v.(*DNode) if i == idx-1 { return iter.cur } @@ -191,7 +191,7 @@ func (iter *Iterator) Prev() (result bool) { } if v, ok := iter.tstack.Pop(); ok { - iter.cur = v.(*Node) + iter.cur = v.(*DNode) iter.curPushPrevStack(iter.cur) return true } @@ -200,14 +200,14 @@ func (iter *Iterator) Prev() (result bool) { return false } -func getRelationship(cur *Node) int { +func getRelationship(cur *DNode) int { if cur.family[0].family[2] == cur { return 2 } return 1 } -func (iter *Iterator) getPrevUp(cur *Node) *Node { +func (iter *Iterator) getPrevUp(cur *DNode) *DNode { for cur.family[0] != nil { if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序 return cur.family[0] @@ -217,7 +217,7 @@ func (iter *Iterator) getPrevUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushPrevStack(cur *Node) { +func (iter *Iterator) curPushPrevStack(cur *DNode) { Prev := cur.family[1] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值 if Prev != nil { @@ -229,7 +229,7 @@ func (iter *Iterator) curPushPrevStack(cur *Node) { } } -func (iter *Iterator) getNextUp(cur *Node) *Node { +func (iter *Iterator) getNextUp(cur *DNode) *DNode { for cur.family[0] != nil { if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序 return cur.family[0] @@ -239,7 +239,7 @@ func (iter *Iterator) getNextUp(cur *Node) *Node { return nil } -func (iter *Iterator) curPushNextStack(cur *Node) { +func (iter *Iterator) curPushNextStack(cur *DNode) { next := cur.family[2] if next != nil { diff --git a/tree/lsv/lsv.go b/tree/lsv/dtree.go similarity index 90% rename from tree/lsv/lsv.go rename to tree/lsv/dtree.go index 81896cf..35540a4 100644 --- a/tree/lsv/lsv.go +++ b/tree/lsv/dtree.go @@ -4,28 +4,16 @@ import ( "github.com/davecgh/go-spew/spew" ) -// NodeType 节点类型 -type NodeType int - -const ( - - // Split 分型类型 = 0 - Split NodeType = iota - // Data 数据集 - Data -) - // DNode 节点 type DNode struct { family [3]*DNode size int - ntype NodeType // 节点类型 key []rune value []rune } -// Tree 树 -type Tree struct { +// DTree 用于数据的树 +type DTree struct { root *DNode feature *DNode Compare func(s1, s2 []rune) int @@ -83,12 +71,12 @@ func (n *DNode) String() string { // var _ tree.IBSTreeDupKey = (*Tree)(nil) // } -// New 创建一个树 -func New(Compare func(s1, s2 []rune) int) *Tree { - return &Tree{Compare: Compare, iter: NewIteratorWithCap(nil, 16)} +// newDataTree 创建一个树 +func newDataTree(Compare func(s1, s2 []rune) int) *DTree { + return &DTree{Compare: Compare, iter: NewIteratorWithCap(nil, 16)} } -func (tree *Tree) String() string { +func (tree *DTree) String() string { str := "VBTree-Dup\n" if tree.root == nil { return str + "nil" @@ -97,11 +85,11 @@ func (tree *Tree) String() string { return str } -func (tree *Tree) Iterator() *Iterator { +func (tree *DTree) Iterator() *Iterator { return initIterator(tree) } -func (tree *Tree) Size() int { +func (tree *DTree) Size() int { if tree.root == nil { return 0 } @@ -109,7 +97,7 @@ func (tree *Tree) Size() int { } // IndexNode 索引节点 -func (tree *Tree) IndexNode(idx int) *DNode { +func (tree *DTree) IndexNode(idx int) *DNode { cur := tree.root if idx >= 0 { for cur != nil { @@ -140,7 +128,7 @@ func (tree *Tree) IndexNode(idx int) *DNode { return nil } -func (tree *Tree) Index(idx int) (interface{}, bool) { +func (tree *DTree) Index(idx int) (interface{}, bool) { n := tree.IndexNode(idx) if n != nil { return n.value, true @@ -148,7 +136,7 @@ func (tree *Tree) Index(idx int) (interface{}, bool) { return nil, false } -func (tree *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1 +func (tree *DTree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1 if idx1^idx2 < 0 { if idx1 < 0 { @@ -208,7 +196,7 @@ func (tree *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { / return nil, false } -func (tree *Tree) RemoveIndex(idx int) (interface{}, bool) { +func (tree *DTree) RemoveIndex(idx int) (interface{}, bool) { n := tree.IndexNode(idx) if n != nil { tree.RemoveNode(n) @@ -217,7 +205,7 @@ func (tree *Tree) RemoveIndex(idx int) (interface{}, bool) { return nil, false } -func (tree *Tree) RemoveNode(n *DNode) { +func (tree *DTree) RemoveNode(n *DNode) { if tree.root.size == 1 { tree.root = nil tree.feature = nil @@ -282,7 +270,7 @@ func (tree *Tree) RemoveNode(n *DNode) { return } -func (tree *Tree) Remove(key []rune) (interface{}, bool) { +func (tree *DTree) Remove(key []rune) (interface{}, bool) { if n, ok := tree.GetNode(key); ok { tree.RemoveNode(n) @@ -292,13 +280,13 @@ func (tree *Tree) Remove(key []rune) (interface{}, bool) { return nil, false } -func (tree *Tree) Clear() { +func (tree *DTree) Clear() { tree.root = nil tree.iter = NewIteratorWithCap(nil, 16) } // Values 返回先序遍历的值 -func (tree *Tree) Values() [][]rune { +func (tree *DTree) Values() [][]rune { mszie := 0 if tree.root != nil { mszie = tree.root.size @@ -311,7 +299,7 @@ func (tree *Tree) Values() [][]rune { return result } -func (tree *Tree) GetRange(k1, k2 []rune) (result []interface{}) { +func (tree *DTree) GetRange(k1, k2 []rune) (result []interface{}) { c := tree.Compare(k2, k1) switch c { case 1: @@ -377,7 +365,7 @@ func (tree *Tree) GetRange(k1, k2 []rune) (result []interface{}) { return } -func (tree *Tree) GetString(key string) (interface{}, bool) { +func (tree *DTree) GetString(key string) (interface{}, bool) { n, ok := tree.GetNode([]rune(key)) if ok { return n.value, true @@ -385,7 +373,7 @@ func (tree *Tree) GetString(key string) (interface{}, bool) { return n, false } -func (tree *Tree) Get(key []rune) ([]rune, bool) { +func (tree *DTree) Get(key []rune) ([]rune, bool) { n, ok := tree.GetNode(key) if ok { return n.value, true @@ -393,7 +381,7 @@ func (tree *Tree) Get(key []rune) ([]rune, bool) { return nil, false } -func (tree *Tree) GetAround(key []rune) (result [3]interface{}) { +func (tree *DTree) GetAround(key []rune) (result [3]interface{}) { an := tree.getArountNode(key) for i, n := range an { if n != nil { @@ -403,7 +391,7 @@ func (tree *Tree) GetAround(key []rune) (result [3]interface{}) { return } -func (tree *Tree) getArountNode(key []rune) (result [3]*DNode) { +func (tree *DTree) getArountNode(key []rune) (result [3]*DNode) { var last *DNode var lastc int @@ -468,7 +456,7 @@ func (tree *Tree) getArountNode(key []rune) (result [3]*DNode) { return } -func (tree *Tree) GetNode(key []rune) (*DNode, bool) { +func (tree *DTree) GetNode(key []rune) (*DNode, bool) { for n := tree.root; n != nil; { switch c := tree.Compare(key, n.key); c { @@ -497,11 +485,11 @@ func (tree *Tree) GetNode(key []rune) (*DNode, bool) { } // PutString Key Value with Type string -func (tree *Tree) PutString(key, value string) (isInsert bool) { +func (tree *DTree) PutString(key, value string) (isInsert bool) { return tree.Put([]rune(key), []rune(value)) } -func (tree *Tree) putfeature(node *DNode) { +func (tree *DTree) putfeature(node *DNode) { for cur := tree.root; cur != nil; cur = cur.family[2] { cur.size++ if cur.family[2] == nil { @@ -513,7 +501,7 @@ func (tree *Tree) putfeature(node *DNode) { } // Put return bool -func (tree *Tree) Put(key, value []rune) (isInsert bool) { +func (tree *DTree) Put(key, value []rune) (isInsert bool) { if tree.root == nil { node := &DNode{key: key, value: value, size: 1} @@ -611,7 +599,7 @@ const ( ) // Traversal 遍历的方法 默认是LDR 从小到大 Compare 为 l < r -func (tree *Tree) Traversal(every func(k, v []rune) bool, traversalMethod ...interface{}) { +func (tree *DTree) Traversal(every func(k, v []rune) bool, traversalMethod ...interface{}) { if tree.root == nil { return } @@ -733,7 +721,7 @@ func (tree *Tree) Traversal(every func(k, v []rune) bool, traversalMethod ...int } } -func (tree *Tree) lrrotate3(cur *DNode) { +func (tree *DTree) lrrotate3(cur *DNode) { const l = 2 const r = 1 @@ -756,7 +744,7 @@ func (tree *Tree) lrrotate3(cur *DNode) { cur.family[l].size = 1 } -func (tree *Tree) lrrotate(cur *DNode) { +func (tree *DTree) lrrotate(cur *DNode) { const l = 2 const r = 1 @@ -796,7 +784,7 @@ func (tree *Tree) lrrotate(cur *DNode) { cur.size = getChildrenSumSize(cur) + 1 } -func (tree *Tree) rlrotate3(cur *DNode) { +func (tree *DTree) rlrotate3(cur *DNode) { const l = 1 const r = 2 @@ -819,7 +807,7 @@ func (tree *Tree) rlrotate3(cur *DNode) { cur.family[l].size = 1 } -func (tree *Tree) rlrotate(cur *DNode) { +func (tree *DTree) rlrotate(cur *DNode) { const l = 1 const r = 2 @@ -857,7 +845,7 @@ func (tree *Tree) rlrotate(cur *DNode) { cur.size = getChildrenSumSize(cur) + 1 } -func (tree *Tree) rrotate3(cur *DNode) { +func (tree *DTree) rrotate3(cur *DNode) { const l = 1 const r = 2 // 1 right 0 left @@ -875,7 +863,7 @@ func (tree *Tree) rrotate3(cur *DNode) { mov.size = 1 } -func (tree *Tree) rrotate(cur *DNode) { +func (tree *DTree) rrotate(cur *DNode) { const l = 1 const r = 2 @@ -910,7 +898,7 @@ func (tree *Tree) rrotate(cur *DNode) { cur.size = getChildrenSumSize(cur) + 1 } -func (tree *Tree) lrotate3(cur *DNode) { +func (tree *DTree) lrotate3(cur *DNode) { const l = 2 const r = 1 // 1 right 0 left @@ -928,7 +916,7 @@ func (tree *Tree) lrotate3(cur *DNode) { mov.size = 1 } -func (tree *Tree) lrotate(cur *DNode) { +func (tree *DTree) lrotate(cur *DNode) { const l = 2 const r = 1 @@ -978,7 +966,7 @@ func getSize(cur *DNode) int { return cur.size } -func (tree *Tree) fixSizeWithRemove(cur *DNode) { +func (tree *DTree) fixSizeWithRemove(cur *DNode) { for cur != nil { cur.size-- if cur.size > 8 { @@ -1006,7 +994,7 @@ func (tree *Tree) fixSizeWithRemove(cur *DNode) { } } -func (tree *Tree) fixSize(cur *DNode, ls, rs int) { +func (tree *DTree) fixSize(cur *DNode, ls, rs int) { if ls > rs { llsize, lrsize := getChildrenSize(cur.family[1]) if lrsize > llsize { @@ -1095,7 +1083,7 @@ func outputfordebug(node *DNode, prefix string, isTail bool, str *string) { } } -func (tree *Tree) debugString() string { +func (tree *DTree) debugString() string { str := "VBTree-Dup\n" if tree.root == nil { return str + "nil" diff --git a/tree/lsv/inode.go b/tree/lsv/itree.go similarity index 86% rename from tree/lsv/inode.go rename to tree/lsv/itree.go index 44a043e..8ebe1bb 100644 --- a/tree/lsv/inode.go +++ b/tree/lsv/itree.go @@ -4,15 +4,14 @@ package lsv type INode struct { family [3]*INode size int - - tree *Tree + tree *DTree } // NewINode 生成inode节点 func NewINode() *INode { inode := &INode{} inode.size = 1 - inode.tree = New(compareRunes) + inode.tree = newDataTree(compareRunes) return inode } @@ -23,6 +22,11 @@ type ITree struct { Compare func(s1, s2 []rune) int } +// New 生成一颗索引树 +func New(Compare func(s1, s2 []rune) int) *ITree { + return &ITree{Compare: Compare, limit: 100} +} + // Put return bool func (tree *ITree) Put(key, value []rune) (isInsert bool) { @@ -57,6 +61,8 @@ func (tree *ITree) Put(key, value []rune) (isInsert bool) { // 根树 新节点要插入到 右节点的最小值位置 即是 左~ irnode := NewINode() irnode.tree.root = rspilt + irnode.tree.feature = cur.tree.feature + icur := cur.family[2] if icur == nil { cur.family[2] = irnode @@ -72,11 +78,11 @@ func (tree *ITree) Put(key, value []rune) (isInsert bool) { } // 调整3节点失衡的情况 - if icur.family[0] != nil && icur.family[0].size == 3 { - if icur.family[0].family[2] == nil { - tree.irlrotate3(icur.family[0]) + if cur.family[0] != nil && cur.family[0].size == 3 { + if cur.family[0].family[1] == nil { + tree.ilrrotate3(cur.family[0]) } else { - tree.ilrotate3(icur.family[0]) + tree.irrotate3(cur.family[0]) } } } @@ -193,6 +199,10 @@ func (tree *ITree) Put(key, value []rune) (isInsert bool) { } } +func (tree *ITree) String() { + +} + func (tree *ITree) ifixSize(cur *INode, ls, rs int) { if ls > rs { llsize, lrsize := igetChildrenSize(cur.family[1]) @@ -218,7 +228,7 @@ func (tree *ITree) ilrrotate3(cur *INode) { movparent := cur.family[l] mov := movparent.family[r] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 cur.family[r] = mov mov.family[0] = cur @@ -229,8 +239,6 @@ func (tree *ITree) ilrrotate3(cur *INode) { cur.family[r] = mov mov.family[0] = cur - // cur.size = 3 - // cur.family[r].size = 1 cur.family[l].size = 1 } @@ -242,7 +250,7 @@ func (tree *ITree) ilrrotate(cur *INode) { movparent := cur.family[l] mov := movparent.family[r] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 if mov.family[l] != nil { movparent.family[r] = mov.family[l] @@ -281,7 +289,7 @@ func (tree *ITree) irlrotate3(cur *INode) { movparent := cur.family[l] mov := movparent.family[r] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 cur.family[r] = mov mov.family[0] = cur @@ -305,7 +313,7 @@ func (tree *ITree) irlrotate(cur *INode) { movparent := cur.family[l] mov := movparent.family[r] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 if mov.family[l] != nil { movparent.family[r] = mov.family[l] @@ -341,7 +349,7 @@ func (tree *ITree) irrotate3(cur *INode) { // 1 right 0 left mov := cur.family[l] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 cur.family[r] = mov @@ -360,7 +368,7 @@ func (tree *ITree) irrotate(cur *INode) { // 1 right 0 left mov := cur.family[l] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 // mov.family[l]不可能为nil mov.family[l].family[0] = cur @@ -394,7 +402,7 @@ func (tree *ITree) ilrotate3(cur *INode) { // 1 right 0 left mov := cur.family[l] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 cur.family[r] = mov @@ -413,7 +421,7 @@ func (tree *ITree) ilrotate(cur *INode) { // 1 right 0 left mov := cur.family[l] - mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移 // mov.family[l]不可能为nil mov.family[l].family[0] = cur @@ -456,27 +464,27 @@ func igetSize(cur *INode) int { return cur.size } -func (tree *ITree) fixSizeWithRemove(cur *INode) { +func (tree *ITree) ifixSizeWithRemove(cur *INode) { for cur != nil { cur.size-- if cur.size > 8 { factor := cur.size / 10 // or factor = 1 - ls, rs := getChildrenSize(cur) + ls, rs := igetChildrenSize(cur) if rs >= ls*2+factor || ls >= rs*2+factor { - tree.fixSize(cur, ls, rs) + tree.ifixSize(cur, ls, rs) } } else if cur.size == 3 { if cur.family[1] == nil { if cur.family[2].family[1] == nil { - tree.lrotate3(cur) + tree.ilrotate3(cur) } else { - tree.lrrotate3(cur) + tree.ilrrotate3(cur) } } else if cur.family[2] == nil { if cur.family[1].family[2] == nil { - tree.rrotate3(cur) + tree.irrotate3(cur) } else { - tree.rlrotate3(cur) + tree.irlrotate3(cur) } } } diff --git a/tree/lsv/lsv_test.go b/tree/lsv/lsv_test.go index 86e2304..cb9ed0e 100644 --- a/tree/lsv/lsv_test.go +++ b/tree/lsv/lsv_test.go @@ -2,6 +2,7 @@ package lsv import ( "sort" + "strconv" "testing" "github.com/Pallinder/go-randomdata" @@ -349,8 +350,21 @@ func loadTestData() [][]rune { // // } // // } -func TestValues(t *testing.T) { +func TestPut(t *testing.T) { tree := New(compareRunes) + + for i := 0; i < 10000; i++ { + v := randomdata.FullDate() + ":" + strconv.Itoa(i) + randomdata.Street() + tree.Put([]rune(v), []rune(v)) + if tree.root.size == 2 { + t.Error("213") + } + } + t.Error("123") +} + +func TestValues(t *testing.T) { + tree := newDataTree(compareRunes) var testdata = []string{"abc", "bca", "12xx", "ABC", "你好"} for _, v := range testdata { @@ -367,7 +381,7 @@ func TestValues(t *testing.T) { } func TestGet(t *testing.T) { - tree := New(compareRunes) + tree := newDataTree(compareRunes) var testdata = []string{"asdb", "bsas", "asdba"} for _, v := range testdata { tree.PutString(v, v) @@ -820,7 +834,7 @@ func BenchmarkPut(b *testing.B) { execCount := 50 b.N = len(l) * execCount for i := 0; i < execCount; i++ { - tree := New(compareRunes) + tree := newDataTree(compareRunes) for _, v := range l { tree.Put(v, v) }