diff --git a/README.md b/README.md index 90e688b..0ae0a5e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # structure -暂时没时间整理, 后期才整理完整 +暂时没时间整理, 后期才整理完整. ## PriorityQueue diff --git a/tree/lsv/inode.go b/tree/lsv/inode.go new file mode 100644 index 0000000..44a043e --- /dev/null +++ b/tree/lsv/inode.go @@ -0,0 +1,485 @@ +package lsv + +// INode 用于索引的节点 +type INode struct { + family [3]*INode + size int + + tree *Tree +} + +// NewINode 生成inode节点 +func NewINode() *INode { + inode := &INode{} + inode.size = 1 + inode.tree = New(compareRunes) + return inode +} + +// ITree 用于索引的树 +type ITree struct { + root *INode + limit int + Compare func(s1, s2 []rune) int +} + +// Put return bool +func (tree *ITree) Put(key, value []rune) (isInsert bool) { + + // node := &INode{key: key, value: value, size: 1} + if tree.root == nil { + + tree.root = NewINode() + return tree.root.tree.Put(key, value) + + } + + for cur := tree.root; ; { + + if cur.size > 8 { + factor := cur.size / 10 // or factor = 1 + ls, rs := cur.family[1].size, cur.family[2].size + if rs >= ls*2+factor || ls >= rs*2+factor { + tree.ifixSize(cur, ls, rs) + } + } + + c := tree.Compare(key, cur.tree.feature.key) + switch { + case c < 0: + if cur.family[1] == nil { + + if cur.tree.root.size >= tree.limit { + // 子树的节点分解 操作 + lspilt := cur.tree.root.family[1] + rspilt := cur.tree.root.family[2] + + // 根树 新节点要插入到 右节点的最小值位置 即是 左~ + irnode := NewINode() + irnode.tree.root = rspilt + icur := cur.family[2] + if icur == nil { + cur.family[2] = irnode + } else { + for ; icur.family[1] != nil; icur = icur.family[1] { + } + + icur.family[1] = irnode + irnode.family[0] = icur + + for temp := icur; temp != nil; temp = temp.family[0] { + temp.size++ + } + + // 调整3节点失衡的情况 + if icur.family[0] != nil && icur.family[0].size == 3 { + if icur.family[0].family[2] == nil { + tree.irlrotate3(icur.family[0]) + } else { + tree.ilrotate3(icur.family[0]) + } + } + } + + rspilt.family[0] = nil + + tempRoot := cur.tree.root + + lspilt.family[0] = nil + cur.tree.root = lspilt + + tempRoot.size = 1 + for i := 1; i < len(tempRoot.family); i++ { + tempRoot.family[i] = nil + } + + cur.tree.putfeature(tempRoot) + } + + return cur.tree.Put(key, value) + + // inode := NewINode() + // cur.family[1] = inode + // inode.family[0] = cur + + // for temp := cur; temp != nil; temp = temp.family[0] { + // temp.size++ + // } + + // if cur.family[0] != nil && cur.family[0].size == 3 { + // if cur.family[0].family[1] == nil { + // tree.ilrrotate3(cur.family[0]) + // } else { + // tree.irrotate3(cur.family[0]) + // } + // } + // return true + } + cur = cur.family[1] + case c > 0: + if cur.family[2] == nil { + + if cur.tree.root.size >= tree.limit { + lspilt := cur.tree.root.family[1] + rspilt := cur.tree.root.family[2] + // cur.family + irnode := NewINode() + irnode.tree.root = rspilt + icur := cur.family[2] + if icur == nil { + cur.family[2] = irnode + } else { + for ; icur.family[1] != nil; icur = icur.family[1] { + } + + icur.family[1] = irnode + irnode.family[0] = icur + + for temp := icur; temp != nil; temp = temp.family[0] { + temp.size++ + } + + // 调整3节点失衡的情况 + if icur.family[0] != nil && icur.family[0].size == 3 { + if icur.family[0].family[2] == nil { + tree.irlrotate3(icur.family[0]) + } else { + tree.ilrotate3(icur.family[0]) + } + } + } + + rspilt.family[0] = nil + + // cur.family irnode + + tempRoot := cur.tree.root + + lspilt.family[0] = nil + cur.tree.root = lspilt + + tempRoot.size = 1 + for i := 1; i < len(tempRoot.family); i++ { + tempRoot.family[i] = nil + } + + cur.tree.putfeature(tempRoot) + } + + return cur.tree.Put(key, value) + + // inode := NewINode() + // cur.family[2] = inode + // inode.family[0] = cur + + // for temp := cur; temp != nil; temp = temp.family[0] { + // temp.size++ + // } + + // if cur.family[0] != nil && cur.family[0].size == 3 { + // if cur.family[0].family[2] == nil { + // tree.irlrotate3(cur.family[0]) + // } else { + // tree.ilrotate3(cur.family[0]) + // } + // } + // return true + } + cur = cur.family[2] + default: + return cur.tree.Put(key, value) + } + + } +} + +func (tree *ITree) ifixSize(cur *INode, ls, rs int) { + if ls > rs { + llsize, lrsize := igetChildrenSize(cur.family[1]) + if lrsize > llsize { + tree.irlrotate(cur) + } else { + tree.irrotate(cur) + } + } else { + rlsize, rrsize := igetChildrenSize(cur.family[2]) + if rlsize > rrsize { + tree.ilrrotate(cur) + } else { + tree.ilrotate(cur) + } + } +} + +func (tree *ITree) ilrrotate3(cur *INode) { + const l = 2 + const r = 1 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + mov.family[0] = cur + + cur.family[l] = movparent + movparent.family[r] = nil + + cur.family[r] = mov + mov.family[0] = cur + + // cur.size = 3 + // cur.family[r].size = 1 + cur.family[l].size = 1 +} + +func (tree *ITree) ilrrotate(cur *INode) { + + const l = 2 + const r = 1 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + if mov.family[l] != nil { + movparent.family[r] = mov.family[l] + movparent.family[r].family[0] = movparent + //movparent.family[r].child = l + } else { + movparent.family[r] = nil + } + + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + //mov.family[l].child = l + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + cur.family[r] = mov + mov.family[0] = cur + + movparent.size = igetChildrenSumSize(movparent) + 1 + mov.size = igetChildrenSumSize(mov) + 1 + cur.size = igetChildrenSumSize(cur) + 1 +} + +func (tree *ITree) irlrotate3(cur *INode) { + const l = 1 + const r = 2 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + mov.family[0] = cur + + cur.family[l] = movparent + movparent.family[r] = nil + + cur.family[r] = mov + mov.family[0] = cur + + // cur.size = 3 + // cur.family[r].size = 1 + cur.family[l].size = 1 +} + +func (tree *ITree) irlrotate(cur *INode) { + + const l = 1 + const r = 2 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + if mov.family[l] != nil { + movparent.family[r] = mov.family[l] + movparent.family[r].family[0] = movparent + } else { + movparent.family[r] = nil + } + + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + cur.family[r] = mov + mov.family[0] = cur + + movparent.size = igetChildrenSumSize(movparent) + 1 + mov.size = igetChildrenSumSize(mov) + 1 + cur.size = igetChildrenSumSize(cur) + 1 +} + +func (tree *ITree) irrotate3(cur *INode) { + const l = 1 + const r = 2 + // 1 right 0 left + mov := cur.family[l] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + + cur.family[l] = mov.family[l] + cur.family[l].family[0] = cur + + mov.family[l] = nil + + mov.size = 1 +} + +func (tree *ITree) irrotate(cur *INode) { + + const l = 1 + const r = 2 + // 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.family[l]不可能为nil + mov.family[l].family[0] = cur + + cur.family[l] = mov.family[l] + + // 解决mov节点孩子转移的问题 + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.family[r] = mov + + mov.size = igetChildrenSumSize(mov) + 1 + cur.size = igetChildrenSumSize(cur) + 1 +} + +func (tree *ITree) ilrotate3(cur *INode) { + const l = 2 + const r = 1 + // 1 right 0 left + mov := cur.family[l] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + + cur.family[l] = mov.family[l] + cur.family[l].family[0] = cur + + mov.family[l] = nil + + mov.size = 1 +} + +func (tree *ITree) ilrotate(cur *INode) { + + const l = 2 + const r = 1 + // 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.family[l]不可能为nil + mov.family[l].family[0] = cur + + cur.family[l] = mov.family[l] + + // 解决mov节点孩子转移的问题 + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.family[r] = mov + + mov.size = igetChildrenSumSize(mov) + 1 + cur.size = igetChildrenSumSize(cur) + 1 +} + +func igetChildrenSumSize(cur *INode) int { + return igetSize(cur.family[1]) + igetSize(cur.family[2]) +} + +func igetChildrenSize(cur *INode) (int, int) { + return igetSize(cur.family[1]), igetSize(cur.family[2]) +} + +func igetSize(cur *INode) int { + if cur == nil { + return 0 + } + return cur.size +} + +func (tree *ITree) fixSizeWithRemove(cur *INode) { + for cur != nil { + cur.size-- + if cur.size > 8 { + factor := cur.size / 10 // or factor = 1 + ls, rs := getChildrenSize(cur) + if rs >= ls*2+factor || ls >= rs*2+factor { + tree.fixSize(cur, ls, rs) + } + } else if cur.size == 3 { + if cur.family[1] == nil { + if cur.family[2].family[1] == nil { + tree.lrotate3(cur) + } else { + tree.lrrotate3(cur) + } + } else if cur.family[2] == nil { + if cur.family[1].family[2] == nil { + tree.rrotate3(cur) + } else { + tree.rlrotate3(cur) + } + } + } + cur = cur.family[0] + } +} diff --git a/tree/lsv/iterator.go b/tree/lsv/iterator.go new file mode 100644 index 0000000..f39682f --- /dev/null +++ b/tree/lsv/iterator.go @@ -0,0 +1,252 @@ +package lsv + +import ( + lastack "github.com/474420502/focus/stack/listarraystack" +) + +type Iterator struct { + dir int + up *Node + cur *Node + tstack *lastack.Stack + // curnext *Node +} + +func initIterator(avltree *Tree) *Iterator { + 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 NewIteratorWithCap(n *Node, cap int) *Iterator { + iter := &Iterator{tstack: lastack.NewWithCap(cap)} + iter.up = n + return iter +} + +func (iter *Iterator) GetNode() *Node { + return iter.cur +} + +func (iter *Iterator) ToHead() { + if iter.cur == nil { + iter.cur = iter.up + } + + for iter.cur.family[0] != nil { + iter.cur = iter.cur.family[0] + } + + for iter.cur.family[1] != nil { + iter.cur = iter.cur.family[1] + } + iter.SetNode(iter.cur) + iter.cur = nil +} + +func (iter *Iterator) ToTail() { + + if iter.cur == nil { + iter.cur = iter.up + } + + for iter.cur.family[0] != nil { + iter.cur = iter.cur.family[0] + } + + for iter.cur.family[2] != nil { + iter.cur = iter.cur.family[2] + } + iter.SetNode(iter.cur) + iter.cur = nil +} + +func (iter *Iterator) SetNode(n *Node) { + iter.up = n + iter.dir = 0 + iter.tstack.Clear() +} + +func (iter *Iterator) Key() interface{} { + return iter.cur.key +} + +func (iter *Iterator) Value() interface{} { + return iter.cur.value +} + +func (iter *Iterator) GetNext(cur *Node, idx int) *Node { + + // iter := NewIterator(cur) + iter.SetNode(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) + } + + 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 + } + } + + return cur +} + +func (iter *Iterator) Next() (result bool) { + + if iter.dir > -1 { + if iter.dir == 1 && iter.cur != nil { + iter.tstack.Clear() + iter.curPushNextStack(iter.cur) + iter.up = iter.getNextUp(iter.cur) + } + iter.dir = -1 + } + + if iter.tstack.Size() == 0 { + if iter.up == nil { + return false + } + iter.tstack.Push(iter.up) + iter.up = iter.getNextUp(iter.up) + } + + if v, ok := iter.tstack.Pop(); ok { + iter.cur = v.(*Node) + iter.curPushNextStack(iter.cur) + return true + } + + return false +} +func (iter *Iterator) GetPrev(cur *Node, idx int) *Node { + + // iter := NewIterator(cur) + iter.SetNode(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 +} + +func getRelationship(cur *Node) int { + if cur.family[0].family[2] == cur { + return 2 + } + return 1 +} + +func (iter *Iterator) getPrevUp(cur *Node) *Node { + for cur.family[0] != nil { + if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序 + return cur.family[0] + } + cur = cur.family[0] + } + return nil +} + +func (iter *Iterator) curPushPrevStack(cur *Node) { + Prev := cur.family[1] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值 + + if Prev != nil { + iter.tstack.Push(Prev) + for Prev.family[2] != nil { + Prev = Prev.family[2] + iter.tstack.Push(Prev) // 入栈 用于回溯 + } + } +} + +func (iter *Iterator) getNextUp(cur *Node) *Node { + for cur.family[0] != nil { + if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序 + return cur.family[0] + } + cur = cur.family[0] + } + return nil +} + +func (iter *Iterator) curPushNextStack(cur *Node) { + next := cur.family[2] + + if next != nil { + iter.tstack.Push(next) + for next.family[1] != nil { + next = next.family[1] + iter.tstack.Push(next) + } + } +} diff --git a/tree/lsv/iterator_test.go b/tree/lsv/iterator_test.go new file mode 100644 index 0000000..2dda4f0 --- /dev/null +++ b/tree/lsv/iterator_test.go @@ -0,0 +1,28 @@ +package lsv + +// func TestIerator(t *testing.T) { +// tree := New(compare.Int) +// l := []int{5, 10, 100, 30, 40, 70, 45, 35, 23} +// for _, v := range l { +// tree.Put(v, v) +// } + +// sort.Ints(l) + +// iter := tree.Iterator() +// iter.ToHead() +// for i := 0; iter.Next(); i++ { + +// if iter.Value() != l[i] { +// t.Error(iter.Value(), l[i]) +// } +// } +// iter.ToTail() +// iter.Prev() +// for i := len(l) - 1; iter.Next(); i-- { + +// if iter.Value() != l[i] { +// t.Error(iter.Value(), l[i]) +// } +// } +// } diff --git a/tree/lsv/lsv.go b/tree/lsv/lsv.go new file mode 100644 index 0000000..81896cf --- /dev/null +++ b/tree/lsv/lsv.go @@ -0,0 +1,1105 @@ +package lsv + +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 { + root *DNode + feature *DNode + Compare func(s1, s2 []rune) int + iter *Iterator +} + +func compareRunes(s1, s2 []rune) int { + switch { + case len(s1) > len(s2): + for i := 0; i < len(s2); i++ { + if s1[i] != s2[i] { + if s1[i] > s2[i] { + return 1 + } + return -1 + } + } + return 1 + case len(s1) < len(s2): + for i := 0; i < len(s1); i++ { + if s1[i] != s2[i] { + if s1[i] > s2[i] { + return 1 + } + return -1 + } + } + return -1 + default: + for i := 0; i < len(s1); i++ { + if s1[i] != s2[i] { + if s1[i] > s2[i] { + return 1 + } + return -1 + } + } + return 0 + } +} + +func (n *DNode) String() string { + if n == nil { + return "nil" + } + + p := "nil" + if n.family[0] != nil { + p = spew.Sprint(n.family[0].value) + } + return spew.Sprint(n.value) + "(" + p + "|" + spew.Sprint(n.size) + ")" +} + +// func assertImplementation() { +// var _ tree.IBSTreeDupKey = (*Tree)(nil) +// } + +// New 创建一个树 +func New(Compare func(s1, s2 []rune) int) *Tree { + return &Tree{Compare: Compare, iter: NewIteratorWithCap(nil, 16)} +} + +func (tree *Tree) String() string { + str := "VBTree-Dup\n" + if tree.root == nil { + return str + "nil" + } + output(tree.root, "", true, &str) + return str +} + +func (tree *Tree) Iterator() *Iterator { + return initIterator(tree) +} + +func (tree *Tree) Size() int { + if tree.root == nil { + return 0 + } + return tree.root.size +} + +// IndexNode 索引节点 +func (tree *Tree) IndexNode(idx int) *DNode { + cur := tree.root + if idx >= 0 { + for cur != nil { + ls := getSize(cur.family[1]) + if idx == ls { + return cur + } else if idx < ls { + cur = cur.family[1] + } else { + idx = idx - ls - 1 + cur = cur.family[2] + } + } + } else { + idx = -idx - 1 + for cur != nil { + rs := getSize(cur.family[2]) + if idx == rs { + return cur + } else if idx < rs { + cur = cur.family[2] + } else { + idx = idx - rs - 1 + cur = cur.family[1] + } + } + } + return nil +} + +func (tree *Tree) Index(idx int) (interface{}, bool) { + n := tree.IndexNode(idx) + if n != nil { + return n.value, true + } + return nil, false +} + +func (tree *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1 + + if idx1^idx2 < 0 { + if idx1 < 0 { + idx1 = tree.root.size + idx1 + } else { + idx2 = tree.root.size + idx2 + } + } + + if idx1 > idx2 { + ok = true + if idx1 >= tree.root.size { + idx1 = tree.root.size - 1 + ok = false + } + + n := tree.IndexNode(idx1) + tree.iter.SetNode(n) + iter := tree.iter + result = make([]interface{}, 0, idx1-idx2) + for i := idx2; i <= idx1; i++ { + if iter.Prev() { + result = append(result, iter.Value()) + } else { + ok = false + return + } + } + + return + + } else { + ok = true + if idx2 >= tree.root.size { + idx2 = tree.root.size - 1 + ok = false + } + + if n := tree.IndexNode(idx1); n != nil { + tree.iter.SetNode(n) + iter := tree.iter + result = make([]interface{}, 0, idx2-idx1) + for i := idx1; i <= idx2; i++ { + if iter.Next() { + result = append(result, iter.Value()) + } else { + ok = false + return + } + } + + return + } + + } + + return nil, false +} + +func (tree *Tree) RemoveIndex(idx int) (interface{}, bool) { + n := tree.IndexNode(idx) + if n != nil { + tree.RemoveNode(n) + return n.value, true + } + return nil, false +} + +func (tree *Tree) RemoveNode(n *DNode) { + if tree.root.size == 1 { + tree.root = nil + tree.feature = nil + // return n + return + } + + if n == tree.feature { + iter := NewIterator(n) + iter.Prev() + tree.feature = iter.cur + } + + ls, rs := getChildrenSize(n) + if ls == 0 && rs == 0 { + p := n.family[0] + p.family[getRelationship(n)] = nil + tree.fixSizeWithRemove(p) + // return n + return + } + + var cur *DNode + if ls > rs { + cur = n.family[1] + for cur.family[2] != nil { + cur = cur.family[2] + } + + cleft := cur.family[1] + cur.family[0].family[getRelationship(cur)] = cleft + if cleft != nil { + cleft.family[0] = cur.family[0] + } + + } else { + cur = n.family[2] + for cur.family[1] != nil { + cur = cur.family[1] + } + + cright := cur.family[2] + cur.family[0].family[getRelationship(cur)] = cright + + if cright != nil { + cright.family[0] = cur.family[0] + } + } + + cparent := cur.family[0] + // 修改为interface 交换 + n.key, n.value, cur.key, cur.value = cur.key, cur.value, n.key, n.value + + // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 + if cparent == n { + tree.fixSizeWithRemove(n) + } else { + tree.fixSizeWithRemove(cparent) + } + + // return cur + return +} + +func (tree *Tree) Remove(key []rune) (interface{}, bool) { + + if n, ok := tree.GetNode(key); ok { + tree.RemoveNode(n) + return n.value, true + } + // return nil + return nil, false +} + +func (tree *Tree) Clear() { + tree.root = nil + tree.iter = NewIteratorWithCap(nil, 16) +} + +// Values 返回先序遍历的值 +func (tree *Tree) Values() [][]rune { + mszie := 0 + if tree.root != nil { + mszie = tree.root.size + } + result := make([][]rune, 0, mszie) + tree.Traversal(func(k, v []rune) bool { + result = append(result, v) + return true + }, LDR) + return result +} + +func (tree *Tree) GetRange(k1, k2 []rune) (result []interface{}) { + c := tree.Compare(k2, k1) + switch c { + case 1: + + var min, max *DNode + 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) + + tree.iter.SetNode(min) + iter := tree.iter + for iter.Next() { + result = append(result, iter.Value()) + if iter.cur == max { + break + } + } + case -1: + + var min, max *DNode + 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) + + tree.iter.SetNode(max) + iter := tree.iter + 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) GetString(key string) (interface{}, bool) { + n, ok := tree.GetNode([]rune(key)) + if ok { + return n.value, true + } + return n, false +} + +func (tree *Tree) Get(key []rune) ([]rune, bool) { + n, ok := tree.GetNode(key) + if ok { + return n.value, true + } + return nil, false +} + +func (tree *Tree) GetAround(key []rune) (result [3]interface{}) { + an := tree.getArountNode(key) + for i, n := range an { + if n != nil { + result[i] = n.value + } + } + return +} + +func (tree *Tree) getArountNode(key []rune) (result [3]*DNode) { + var last *DNode + var lastc int + + for n := tree.root; n != nil; { + last = n + c := tree.Compare(key, n.key) + switch c { + case -1: + n = n.family[1] + lastc = c + case 1: + n = n.family[2] + lastc = c + case 0: + tree.iter.SetNode(n) + iter := tree.iter + 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") + } + } + + switch lastc { + case 1: + + if result[1] != nil { + + result[0] = tree.iter.GetPrev(result[1], 1) + result[2] = tree.iter.GetNext(result[1], 1) + } else { + result[0] = last + result[2] = tree.iter.GetNext(last, 1) + } + + case -1: + + if result[1] != nil { + result[0] = tree.iter.GetPrev(result[1], 1) + result[2] = tree.iter.GetNext(result[1], 1) + } else { + result[2] = last + result[0] = tree.iter.GetPrev(last, 1) + } + + case 0: + + if result[1] == nil { + return + } + result[0] = tree.iter.GetPrev(result[1], 1) + result[2] = tree.iter.GetNext(result[1], 1) + } + return +} + +func (tree *Tree) GetNode(key []rune) (*DNode, bool) { + + for n := tree.root; n != nil; { + switch c := tree.Compare(key, n.key); c { + case -1: + n = n.family[1] + case 1: + n = n.family[2] + case 0: + + tree.iter.SetNode(n) + iter := tree.iter + 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 Compare only is allowed in -1, 0, 1") + } + } + return nil, false +} + +// PutString Key Value with Type string +func (tree *Tree) PutString(key, value string) (isInsert bool) { + return tree.Put([]rune(key), []rune(value)) +} + +func (tree *Tree) putfeature(node *DNode) { + for cur := tree.root; cur != nil; cur = cur.family[2] { + cur.size++ + if cur.family[2] == nil { + cur.family[2] = node + node.family[0] = cur + break + } + } +} + +// Put return bool +func (tree *Tree) Put(key, value []rune) (isInsert bool) { + + if tree.root == nil { + node := &DNode{key: key, value: value, size: 1} + tree.root = node + tree.feature = node + return true + } + + for cur := tree.root; ; { + + if cur.size > 8 { + factor := cur.size / 10 // or factor = 1 + ls, rs := cur.family[1].size, cur.family[2].size + if rs >= ls*2+factor || ls >= rs*2+factor { + tree.fixSize(cur, ls, rs) + } + } + + c := tree.Compare(key, cur.key) + switch { + case c < 0: + if cur.family[1] == nil { + node := &DNode{key: key, value: value, size: 1} + cur.family[1] = node + node.family[0] = cur + + for temp := cur; temp != nil; temp = temp.family[0] { + temp.size++ + } + + if cur.family[0] != nil && cur.family[0].size == 3 { + if cur.family[0].family[1] == nil { + tree.lrrotate3(cur.family[0]) + } else { + tree.rrotate3(cur.family[0]) + } + } + + return true + } + cur = cur.family[1] + case c > 0: + if cur.family[2] == nil { + node := &DNode{key: key, value: value, size: 1} + cur.family[2] = node + node.family[0] = cur + + for temp := cur; temp != nil; temp = temp.family[0] { + temp.size++ + } + + if cur.family[0] != nil && cur.family[0].size == 3 { + if cur.family[0].family[2] == nil { + tree.rlrotate3(cur.family[0]) + } else { + tree.lrotate3(cur.family[0]) + } + } + + if tree.Compare(node.key, tree.feature.key) > 0 { + tree.feature = node + } + return true + } + cur = cur.family[2] + default: + cur.value = value + return false + } + + } +} + +// TraversalMethod 遍历模式 +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(k, v []rune) bool, traversalMethod ...interface{}) { + if tree.root == nil { + return + } + + method := LDR + if len(traversalMethod) != 0 { + method = traversalMethod[0].(TraversalMethod) + } + + switch method { + case DLR: + var traverasl func(cur *DNode) bool + traverasl = func(cur *DNode) bool { + if cur == nil { + return true + } + if !every(cur.key, cur.value) { + return false + } + if !traverasl(cur.family[1]) { + return false + } + if !traverasl(cur.family[2]) { + return false + } + return true + } + traverasl(tree.root) + case LDR: + var traverasl func(cur *DNode) bool + traverasl = func(cur *DNode) bool { + if cur == nil { + return true + } + if !traverasl(cur.family[1]) { + return false + } + if !every(cur.key, cur.value) { + return false + } + if !traverasl(cur.family[2]) { + return false + } + return true + } + traverasl(tree.root) + case LRD: + var traverasl func(cur *DNode) bool + traverasl = func(cur *DNode) bool { + if cur == nil { + return true + } + if !traverasl(cur.family[1]) { + return false + } + if !traverasl(cur.family[2]) { + return false + } + if !every(cur.key, cur.value) { + return false + } + return true + } + traverasl(tree.root) + case DRL: + var traverasl func(cur *DNode) bool + traverasl = func(cur *DNode) bool { + if cur == nil { + return true + } + if !every(cur.key, cur.value) { + return false + } + if !traverasl(cur.family[1]) { + return false + } + if !traverasl(cur.family[2]) { + return false + } + return true + } + traverasl(tree.root) + case RDL: + var traverasl func(cur *DNode) bool + traverasl = func(cur *DNode) bool { + if cur == nil { + return true + } + if !traverasl(cur.family[2]) { + return false + } + if !every(cur.key, cur.value) { + return false + } + if !traverasl(cur.family[1]) { + return false + } + return true + } + traverasl(tree.root) + case RLD: + var traverasl func(cur *DNode) bool + traverasl = func(cur *DNode) bool { + if cur == nil { + return true + } + if !traverasl(cur.family[2]) { + return false + } + if !traverasl(cur.family[1]) { + return false + } + if !every(cur.key, cur.value) { + return false + } + return true + } + traverasl(tree.root) + } +} + +func (tree *Tree) lrrotate3(cur *DNode) { + const l = 2 + const r = 1 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + mov.family[0] = cur + + cur.family[l] = movparent + movparent.family[r] = nil + + cur.family[r] = mov + mov.family[0] = cur + + // cur.size = 3 + // cur.family[r].size = 1 + cur.family[l].size = 1 +} + +func (tree *Tree) lrrotate(cur *DNode) { + + const l = 2 + const r = 1 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + if mov.family[l] != nil { + movparent.family[r] = mov.family[l] + movparent.family[r].family[0] = movparent + //movparent.family[r].child = l + } else { + movparent.family[r] = nil + } + + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + //mov.family[l].child = l + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + cur.family[r] = mov + mov.family[0] = cur + + movparent.size = getChildrenSumSize(movparent) + 1 + mov.size = getChildrenSumSize(mov) + 1 + cur.size = getChildrenSumSize(cur) + 1 +} + +func (tree *Tree) rlrotate3(cur *DNode) { + const l = 1 + const r = 2 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + mov.family[0] = cur + + cur.family[l] = movparent + movparent.family[r] = nil + + cur.family[r] = mov + mov.family[0] = cur + + // cur.size = 3 + // cur.family[r].size = 1 + cur.family[l].size = 1 +} + +func (tree *Tree) rlrotate(cur *DNode) { + + const l = 1 + const r = 2 + + movparent := cur.family[l] + mov := movparent.family[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + if mov.family[l] != nil { + movparent.family[r] = mov.family[l] + movparent.family[r].family[0] = movparent + } else { + movparent.family[r] = nil + } + + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + cur.family[r] = mov + mov.family[0] = cur + + movparent.size = getChildrenSumSize(movparent) + 1 + mov.size = getChildrenSumSize(mov) + 1 + cur.size = getChildrenSumSize(cur) + 1 +} + +func (tree *Tree) rrotate3(cur *DNode) { + const l = 1 + const r = 2 + // 1 right 0 left + mov := cur.family[l] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + + cur.family[l] = mov.family[l] + cur.family[l].family[0] = cur + + mov.family[l] = nil + + mov.size = 1 +} + +func (tree *Tree) rrotate(cur *DNode) { + + const l = 1 + const r = 2 + // 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.family[l]不可能为nil + mov.family[l].family[0] = cur + + cur.family[l] = mov.family[l] + + // 解决mov节点孩子转移的问题 + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.family[r] = mov + + mov.size = getChildrenSumSize(mov) + 1 + cur.size = getChildrenSumSize(cur) + 1 +} + +func (tree *Tree) lrotate3(cur *DNode) { + const l = 2 + const r = 1 + // 1 right 0 left + mov := cur.family[l] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + cur.family[r] = mov + + cur.family[l] = mov.family[l] + cur.family[l].family[0] = cur + + mov.family[l] = nil + + mov.size = 1 +} + +func (tree *Tree) lrotate(cur *DNode) { + + const l = 2 + const r = 1 + // 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.family[l]不可能为nil + mov.family[l].family[0] = cur + + cur.family[l] = mov.family[l] + + // 解决mov节点孩子转移的问题 + if mov.family[r] != nil { + mov.family[l] = mov.family[r] + } else { + mov.family[l] = nil + } + + if cur.family[r] != nil { + mov.family[r] = cur.family[r] + mov.family[r].family[0] = mov + } else { + mov.family[r] = nil + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur.family[r] = mov + + mov.size = getChildrenSumSize(mov) + 1 + cur.size = getChildrenSumSize(cur) + 1 +} + +func getChildrenSumSize(cur *DNode) int { + return getSize(cur.family[1]) + getSize(cur.family[2]) +} + +func getChildrenSize(cur *DNode) (int, int) { + return getSize(cur.family[1]), getSize(cur.family[2]) +} + +func getSize(cur *DNode) int { + if cur == nil { + return 0 + } + return cur.size +} + +func (tree *Tree) fixSizeWithRemove(cur *DNode) { + for cur != nil { + cur.size-- + if cur.size > 8 { + factor := cur.size / 10 // or factor = 1 + ls, rs := getChildrenSize(cur) + if rs >= ls*2+factor || ls >= rs*2+factor { + tree.fixSize(cur, ls, rs) + } + } else if cur.size == 3 { + if cur.family[1] == nil { + if cur.family[2].family[1] == nil { + tree.lrotate3(cur) + } else { + tree.lrrotate3(cur) + } + } else if cur.family[2] == nil { + if cur.family[1].family[2] == nil { + tree.rrotate3(cur) + } else { + tree.rlrotate3(cur) + } + } + } + cur = cur.family[0] + } +} + +func (tree *Tree) fixSize(cur *DNode, ls, rs int) { + if ls > rs { + llsize, lrsize := getChildrenSize(cur.family[1]) + if lrsize > llsize { + tree.rlrotate(cur) + } else { + tree.rrotate(cur) + } + } else { + rlsize, rrsize := getChildrenSize(cur.family[2]) + if rlsize > rrsize { + tree.lrrotate(cur) + } else { + tree.lrotate(cur) + } + } +} + +func output(node *DNode, prefix string, isTail bool, str *string) { + + if node.family[2] != nil { + newPrefix := prefix + if isTail { + newPrefix += "│ " + } else { + newPrefix += " " + } + output(node.family[2], newPrefix, false, str) + } + *str += prefix + if isTail { + *str += "└── " + } else { + *str += "┌── " + } + + *str += spew.Sprint(node.key) + ":" + spew.Sprint(node.value) + "\n" + + if node.family[1] != nil { + newPrefix := prefix + if isTail { + newPrefix += " " + } else { + newPrefix += "│ " + } + output(node.family[1], newPrefix, true, str) + } + +} + +func outputfordebug(node *DNode, prefix string, isTail bool, str *string) { + + if node.family[2] != nil { + newPrefix := prefix + if isTail { + newPrefix += "│ " + } else { + newPrefix += " " + } + outputfordebug(node.family[2], newPrefix, false, str) + } + *str += prefix + if isTail { + *str += "└── " + } else { + *str += "┌── " + } + + suffix := "(" + parentv := "" + if node.family[0] == nil { + parentv = "nil" + } else { + parentv = spew.Sprint(node.family[0].key) + } + suffix += parentv + "|" + spew.Sprint(node.size) + ")" + *str += spew.Sprint(node.key) + suffix + "\n" + + if node.family[1] != nil { + newPrefix := prefix + if isTail { + newPrefix += " " + } else { + newPrefix += "│ " + } + outputfordebug(node.family[1], newPrefix, true, str) + } +} + +func (tree *Tree) debugString() string { + str := "VBTree-Dup\n" + if tree.root == nil { + return str + "nil" + } + outputfordebug(tree.root, "", true, &str) + return str +} diff --git a/tree/lsv/lsv_test.go b/tree/lsv/lsv_test.go new file mode 100644 index 0000000..86e2304 --- /dev/null +++ b/tree/lsv/lsv_test.go @@ -0,0 +1,862 @@ +package lsv + +import ( + "sort" + "testing" + + "github.com/Pallinder/go-randomdata" +) + +func loadTestData() [][]rune { + // data, err := ioutil.ReadFile("../l.log") + // if err != nil { + // log.Println(err) + // } + // var l []int + // decoder := gob.NewDecoder(bytes.NewReader(data)) + // decoder.Decode(&l) + // return l + + var result [][]rune + for i := 0; i < 200000; i++ { + c := randomdata.FullDate() + randomdata.RandStringRunes(6) + result = append(result, []rune(c)) + } + return result +} + +// func TestIteratorHeadTail(t *testing.T) { +// tree := New(compare.Int) +// l := []int{1, 7, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15, 100} +// for _, v := range l { +// tree.Put(v, v) +// } + +// iter := tree.Iterator() +// iter.ToHead() // 从小到大 +// iter.Next() +// if iter.Value() != 1 { +// t.Error("value error", iter.Value()) +// } + +// iter.ToTail() +// iter.Prev() +// if iter.Value() != 100 { +// t.Error("value error", iter.Value()) +// } + +// for n := 0; n < 500; n++ { +// tree := New(compare.Int) +// var results []int +// for i := 0; i < 50; i++ { +// v := randomdata.Number(0, 5000) +// if ok := tree.Put(v, v); ok { +// results = append(results, v) +// } +// } +// result := tree.GetAround(5001) + +// iter = tree.Iterator() +// iter.ToTail() +// iter.Prev() +// if iter.Value() != result[0] { +// t.Error("ToTail error", result, iter.Value()) +// } + +// result = tree.GetAround(-1) + +// iter.ToHead() +// iter.Next() +// if iter.Value() != result[2] { +// t.Error("ToTail error", result, iter.Value()) +// } + +// } + +// } + +// func TestLargePushRemove(t *testing.T) { +// for n := 0; n < 10; n++ { +// tree := New(compare.Int) +// var results []int +// for i := 0; i < 50000; i++ { +// v := randomdata.Number(0, 100000000) +// if ok := tree.Put(v, v); ok { +// results = append(results, v) +// } + +// } + +// if tree.Size() != len(results) { +// t.Error("Szie error", tree.Size(), len(results)) +// } + +// for i := 0; i < len(results)-10; i++ { +// tree.Remove(results[i]) +// } + +// results = results[len(results)-10:] +// if tree.Size() != 10 { +// t.Error("Szie error") +// } +// sort.Slice(results, func(i, j int) bool { +// if results[i] < results[j] { +// return true +// } +// return false +// }) +// if spew.Sprint(results) != spew.Sprint(tree.Values()) { +// t.Error("tree is error") +// } + +// for i := 0; i < 10; i++ { +// v1 := results[i] +// v2, ok := tree.Index(i) +// if !ok { +// t.Error("not ok") +// } +// if v1 != v2 { +// t.Error("v1(", v1, ") != v2(", v2, ")??") +// } +// } + +// tree.Clear() +// if tree.String() != "VBTree-Dup\nnil" { +// t.Error("tree String is error") +// } +// } +// } + +// func TestRemoveIndex(t *testing.T) { +// tree := New(compare.Int) +// l := []int{7, 14, 14, 14, 16, 1, 40, 15} +// for _, v := range l { +// tree.Put(v, v) +// } + +// // [1 7 14 14 14 15 16 40] +// var result string +// result = spew.Sprint(tree.Values()) +// if result != "[1 7 14 15 16 40]" { +// t.Error("result = ", result, " should be [1 7 14 15 16 40]") +// } + +// tree.RemoveIndex(3) +// result = spew.Sprint(tree.Values()) +// if result != "[1 7 14 16 40]" { +// t.Error("result is error") +// } + +// tree.RemoveIndex(-1) +// result = spew.Sprint(tree.Values()) +// if result != "[1 7 14 16]" { +// t.Error("result is error") +// } + +// tree.RemoveIndex(0) +// result = spew.Sprint(tree.Values()) +// if result != "[7 14 16]" { +// t.Error("result is error") +// } + +// if tree.Size() != 3 { +// t.Error("size is error") +// } + +// for tree.Size() != 0 { +// tree.RemoveIndex(0) +// } + +// if tree.root != nil { +// t.Error("tree roor is not error") +// } +// } + +// func TestIndexRange(t *testing.T) { +// tree := New(compare.Int) +// l := []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} +// for _, v := range l { +// tree.Put(v, v) +// } +// // [3 7 14 15 16 17 20 21 30 40 50] +// // t.Error(tree.Values(), tree.Size()) +// // t.Error(tree.debugString()) + +// var result string +// result = spew.Sprint(tree.IndexRange(0, 5)) +// if result != "[3 7 14 15 16 17] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(2, 5)) +// if result != "[14 15 16 17] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(5, 100)) +// if result != "[17 20 21 30 40 50] false" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(10, 0)) // size = 11, index max = 10 +// if result != "[50 40 30 21 20 17 16 15 14 7 3] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(11, 0)) // size = 11, index max = 10 +// if result != "[50 40 30 21 20 17 16 15 14 7 3] false" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(4, 1)) // size = 11, index max = 10 +// if result != "[16 15 14 7] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(-1, -5)) // size = 11, index max = 10 +// if result != "[50 40 30 21 20] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(-1, -11)) // size = 11, index max = 0 - 10 (-1,-11) +// if result != "[50 40 30 21 20 17 16 15 14 7 3] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(-1, -12)) // size = 11, index max = 0 - 10 (-1,-11) +// if result != "[50 40 30 21 20 17 16 15 14 7 3] false" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(-5, -1)) // size = 11, index max = 0 - 10 (-1,-11) +// if result != "[20 21 30 40 50] true" { +// t.Error(result) +// } + +// // [3 7 14 15 16 17 20 21 30 40 50] +// result = spew.Sprint(tree.IndexRange(-5, 5)) // +// if result != "[20 17] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(5, -5)) // +// if result != "[17 20] true" { +// t.Error(result) +// } + +// result = spew.Sprint(tree.IndexRange(-1, 6)) // +// if result != "[50 40 30 21 20] true" { +// t.Error(result) +// } + +// } + +// func TestGetAround(t *testing.T) { +// 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) +// } + +// var Result string + +// Result = spew.Sprint(tree.GetAround(17)) +// if Result != "[16 17 20]" { +// t.Error(tree.Values()) +// t.Error("17 is root, tree.GetAround(17)) is error", Result) +// t.Error(tree.debugString()) +// } + +// Result = spew.Sprint(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 TestPutComparatorRandom(t *testing.T) { + +// // for n := 0; n < 300000; n++ { +// // tree := New(compare.Int) +// // godsavl := avltree.NewWithIntComparator() + +// // content := "" +// // m := make(map[int]int) +// // for i := 0; len(m) < 10; i++ { +// // v := randomdata.Number(0, 65535) +// // if _, ok := m[v]; !ok { +// // m[v] = v +// // content += spew.Sprint(v) + "," +// // tree.Put(v, v) +// // godsavl.Put(v, v) +// // } +// // } + +// // s1 := spew.Sprint(tree.Values()) +// // s2 := spew.Sprint(godsavl.Values()) + +// // if s1 != s2 { +// // t.Error(godsavl.String()) +// // t.Error(tree.debugString()) +// // t.Error(content, n) +// // break +// // } +// // } +// // } + +func TestValues(t *testing.T) { + tree := New(compareRunes) + var testdata = []string{"abc", "bca", "12xx", "ABC", "你好"} + + for _, v := range testdata { + tree.PutString(v, v) + } + + sort.Strings(testdata) + for i, v := range tree.Values() { + if testdata[i] != string(v) { + t.Error(string(v)) + } + } + +} + +func TestGet(t *testing.T) { + tree := New(compareRunes) + var testdata = []string{"asdb", "bsas", "asdba"} + for _, v := range testdata { + tree.PutString(v, v) + } + + for _, v := range testdata { + r, ok := tree.GetString(v) + if !ok && r != v { + t.Error("the val not found ", v) + } + } + + if v, ok := tree.Get([]rune("bsasa")); ok { + t.Error("the val(1000) is not in tree, but is found", v) + } +} + +// func TestDupGetRange(t *testing.T) { +// tree := New(compare.Int) +// for _, v := range []int{5, 10, 13, 5, 17, 1, 2, 10, 40, 30, 1} { +// tree.Put(v, v) +// } + +// result := tree.GetRange(0, 20) +// if spew.Sprint(result) != "[1 2 5 10 13 17]" { +// t.Error(result) +// } + +// result = tree.GetRange(0, 8) +// if spew.Sprint(result) != "[1 2 5]" { +// t.Error(result) +// } + +// result = tree.GetRange(-5, -1) +// if spew.Sprint(result) != "[]" { +// t.Error(result) +// } + +// result = tree.GetRange(7, 20) +// if spew.Sprint(result) != "[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 5 2 1]" { +// t.Error(result) +// } + +// result = tree.GetRange(30, 20) +// if spew.Sprint(result) != "[30]" { +// t.Error(result) +// } + +// } + +// 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 TestTravalsal(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) +// } + +// i := 0 +// var result []interface{} +// tree.Traversal(func(k, v interface{}) bool { +// result = append(result, k) +// i++ +// if i >= 10 { +// return false +// } +// return true +// }) + +// if spew.Sprint(result) != "[1 2 5 6 8 10 13 17 30 40]" { +// t.Error(result) +// } + +// } + +// func TestRemoveAll(t *testing.T) { +// ALL: +// for c := 0; c < 5000; c++ { +// tree := New(compare.Int) +// gods := avltree.NewWithIntComparator() +// var l []int +// m := make(map[int]int) + +// for i := 0; len(l) < 50; i++ { +// v := randomdata.Number(0, 100000) +// if _, ok := m[v]; !ok { +// m[v] = v +// l = append(l, v) +// tree.Put(v, v) +// gods.Put(v, v) +// } +// } + +// for i := 0; i < 50; i++ { + +// tree.Remove(l[i]) +// gods.Remove(l[i]) + +// s1 := spew.Sprint(tree.Values()) +// s2 := spew.Sprint(gods.Values()) +// if s1 != s2 { +// t.Error("avl remove error", "avlsize = ", tree.Size()) +// t.Error(tree.root, i, l[i]) +// t.Error(s1) +// t.Error(s2) +// break ALL +// } +// } +// } +// } + +// func TestRemove(t *testing.T) { + +// ALL: +// for N := 0; N < 5000; N++ { +// tree := New(compare.Int) +// gods := avltree.NewWithIntComparator() + +// var l []int +// m := make(map[int]int) + +// for i := 0; len(l) < 20; i++ { +// v := randomdata.Number(0, 100) +// if _, ok := m[v]; !ok { +// l = append(l, v) +// m[v] = v +// tree.Put(v, v) +// gods.Put(v, v) +// } +// } + +// src1 := tree.String() +// src2 := gods.String() + +// for i := 0; i < 20; i++ { +// tree.Remove(l[i]) +// gods.Remove(l[i]) +// if tree.root != nil && spew.Sprint(gods.Values()) != spew.Sprint(tree.Values()) { +// t.Error(src1) +// t.Error(src2) +// t.Error(tree.debugString()) +// t.Error(gods.String()) +// t.Error(l[i]) +// break ALL +// } +// } +// } +// } + +// func BenchmarkGetRange(b *testing.B) { + +// } + +// func BenchmarkIndexRange(b *testing.B) { +// tree := New(compare.Int) +// l := loadTestData() +// b.N = len(l) + +// for _, v := range l { +// tree.Put(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// execCount := 5 +// b.N = len(l) * execCount + +// for i := 0; i < execCount; i++ { +// for range l { +// tree.IndexRange(i, i+49) +// } +// } +// } + +// func BenchmarkSkipListGet(b *testing.B) { +// sl := skiplist.New(skiplist.Int) +// l := loadTestData() +// b.N = len(l) + +// for _, v := range l { +// sl.Set(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// execCount := 5 +// b.N = len(l) * execCount + +// for i := 0; i < execCount; i++ { +// for _, v := range l { +// sl.Get(v) +// // e := sl.Get(v) +// // var result [50]interface{} +// // for i := 0; i < 50 && e != nil; i++ { +// // result[i] = e.Value +// // e = e.Next() +// // } +// } +// } +// } + +// func BenchmarkSkipListSet(b *testing.B) { + +// l := loadTestData() +// execCount := 1 +// b.N = len(l) * execCount +// for i := 0; i < execCount; i++ { +// sl := skiplist.New(skiplist.Int) +// for _, v := range l { +// sl.Set(v, v) +// } +// } +// } + +// func BenchmarkIterator(b *testing.B) { +// tree := New(compare.Int) + +// l := loadTestData() +// b.N = len(l) + +// for _, v := range l { +// tree.Put(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() +// iter := tree.Iterator() +// b.N = 0 +// for iter.Next() { +// b.N++ +// } +// for iter.Prev() { +// b.N++ +// } +// for iter.Next() { +// b.N++ +// } +// b.Log(b.N, len(l)) +// } + +// func BenchmarkRemove(b *testing.B) { +// tree := New(compare.Int) + +// l := loadTestData() + +// b.N = len(l) +// for _, v := range l { +// tree.Put(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// for i := 0; i < len(l); i++ { +// tree.Remove(l[i]) +// } +// } + +// func BenchmarkGodsRemove(b *testing.B) { +// tree := avltree.NewWithIntComparator() + +// l := loadTestData() + +// b.N = len(l) +// for _, v := range l { +// tree.Put(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// for i := 0; i < len(l); i++ { +// tree.Remove(l[i]) +// } +// } + +// func BenchmarkGodsRBRemove(b *testing.B) { +// tree := redblacktree.NewWithIntComparator() + +// l := loadTestData() + +// b.N = len(l) +// for _, v := range l { +// tree.Put(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// for i := 0; i < len(l); i++ { +// tree.Remove(l[i]) +// } +// } + +// func BenchmarkGet(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 i := 0; i < execCount; i++ { +// for _, v := range l { +// tree.Get(v) +// } +// } +// } + +// func BenchmarkGodsRBGet(b *testing.B) { +// tree := redblacktree.NewWithIntComparator() + +// 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 i := 0; i < execCount; i++ { +// for _, v := range l { +// tree.Get(v) +// } +// } +// } + +// func BenchmarkGodsAvlGet(b *testing.B) { +// tree := avltree.NewWithIntComparator() + +// 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 i := 0; i < execCount; i++ { +// for _, v := range l { +// tree.Get(v) +// } +// } +// } + +func BenchmarkPut(b *testing.B) { + l := loadTestData() + + b.ResetTimer() + b.StartTimer() + + execCount := 50 + b.N = len(l) * execCount + for i := 0; i < execCount; i++ { + tree := New(compareRunes) + for _, v := range l { + tree.Put(v, v) + } + } +} + +// func TestPutStable(t *testing.T) { + +// } + +// func BenchmarkGodsRBPut(b *testing.B) { +// l := loadTestData() + +// b.ResetTimer() +// b.StartTimer() + +// execCount := 50 +// b.N = len(l) * execCount +// for i := 0; i < execCount; i++ { +// tree := redblacktree.NewWithIntComparator() +// for _, v := range l { +// tree.Put(v, v) +// } +// } +// } + +// func BenchmarkGodsPut(b *testing.B) { +// tree := avltree.NewWithIntComparator() + +// l := loadTestData() + +// b.ResetTimer() +// b.StartTimer() + +// b.N = len(l) +// for _, v := range l { +// tree.Put(v, v) +// } +// }