From cbeafe09740e148e3b4b7ea8a5cc7a2ca370d737 Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Sat, 23 Mar 2019 04:04:25 +0800 Subject: [PATCH] compare --- avl/avl.go | 5 - compare/compare.go | 245 ++++++++++++ sbt/iterator.go | 215 ----------- sbt/sbt.go | 904 --------------------------------------------- sbt/sbt_test.go | 649 -------------------------------- vbtkey/vbtkey.go | 6 +- 6 files changed, 247 insertions(+), 1777 deletions(-) create mode 100644 compare/compare.go delete mode 100644 sbt/iterator.go delete mode 100644 sbt/sbt.go delete mode 100644 sbt/sbt_test.go diff --git a/avl/avl.go b/avl/avl.go index 1f4a8f1..ced734b 100644 --- a/avl/avl.go +++ b/avl/avl.go @@ -32,9 +32,6 @@ type Tree struct { } func New(comparator utils.Comparator) *Tree { - if m == nil { - m = make(map[int]int) - } return &Tree{comparator: comparator} } @@ -615,8 +612,6 @@ func (avl *Tree) fixRemoveHeight(cur *Node) { } -var m map[int]int - func (avl *Tree) fixPutHeight(cur *Node) { for { diff --git a/compare/compare.go b/compare/compare.go new file mode 100644 index 0000000..79c77ee --- /dev/null +++ b/compare/compare.go @@ -0,0 +1,245 @@ +package compare + +import "time" + +// Compare 如下 +// k1 > k2 --> 1 +// k1 == k2 --> 0 +// k1 < k2 --> -1 +type Compare func(k1, k2 interface{}) int + +// String comp +func String(k1, k2 interface{}) int { + s1 := k1.(string) + s2 := k2.(string) + + 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 Int(k1, k2 interface{}) int { + c1 := k1.(int) + c2 := k2.(int) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Int8(k1, k2 interface{}) int { + c1 := k1.(int8) + c2 := k2.(int8) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Int16(k1, k2 interface{}) int { + c1 := k1.(int16) + c2 := k2.(int16) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Int32(k1, k2 interface{}) int { + c1 := k1.(int32) + c2 := k2.(int32) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Int64(k1, k2 interface{}) int { + c1 := k1.(int64) + c2 := k2.(int64) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func UInt(k1, k2 interface{}) int { + c1 := k1.(uint) + c2 := k2.(uint) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func UInt8(k1, k2 interface{}) int { + c1 := k1.(uint8) + c2 := k2.(uint8) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func UInt16(k1, k2 interface{}) int { + c1 := k1.(uint16) + c2 := k2.(uint16) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func UInt32(k1, k2 interface{}) int { + c1 := k1.(uint32) + c2 := k2.(uint32) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func UInt64(k1, k2 interface{}) int { + c1 := k1.(uint64) + c2 := k2.(uint64) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Float32(k1, k2 interface{}) int { + c1 := k1.(float32) + c2 := k2.(float32) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Float64(k1, k2 interface{}) int { + c1 := k1.(float64) + c2 := k2.(float64) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Byte(k1, k2 interface{}) int { + c1 := k1.(byte) + c2 := k2.(byte) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Rune(k1, k2 interface{}) int { + c1 := k1.(rune) + c2 := k2.(rune) + switch { + case c1 > c2: + return 1 + case c1 < c2: + return -1 + default: + return 0 + } +} + +func Time(k1, k2 interface{}) int { + c1 := k1.(time.Time) + c2 := k2.(time.Time) + + switch { + case c1.After(c2): + return 1 + case c1.Before(c2): + return -1 + default: + return 0 + } +} diff --git a/sbt/iterator.go b/sbt/iterator.go deleted file mode 100644 index 5e525fb..0000000 --- a/sbt/iterator.go +++ /dev/null @@ -1,215 +0,0 @@ -package avlindex - -import ( - "474420502.top/eson/structure/lastack" -) - -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 (iter *Iterator) Value() interface{} { - return iter.cur.value -} - -func (iter *Iterator) Left() bool { - if iter.cur.children[0] != nil { - iter.dir = 0 - iter.cur = iter.cur.children[0] - return true - } - return false -} - -func (iter *Iterator) Right() bool { - if iter.cur.children[1] != nil { - iter.dir = 0 - iter.cur = iter.cur.children[1] - 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 { - if iter.dir == 1 && iter.cur != nil { - iter.tstack.Clear() - iter.curPushPrevStack(iter.cur) - iter.up = iter.getPrevUp(iter.cur) - } - iter.dir = -1 - } - - 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 - } - - return false -} -func GetNext(cur *Node, idx int) *Node { - - 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) - } - - 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 { // 非 1(next 方向定义 -1 为 prev) - if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈 - iter.tstack.Clear() - iter.curPushNextStack(iter.cur) // 把当前cur计算的逆向回朔 - iter.up = iter.getNextUp(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.getNextUp(iter.up) - } - - if v, ok := iter.tstack.Pop(); ok { - iter.cur = v.(*Node) - iter.curPushNextStack(iter.cur) - return true - } - - // 如果再次计算的栈为空, 则只能返回false - return false -} - -func getRelationship(cur *Node) int { - if cur.parent.children[1] == cur { - return 1 - } - return 0 -} - -func (iter *Iterator) getNextUp(cur *Node) *Node { - for cur.parent != nil { - if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序 - return cur.parent - } - cur = cur.parent - } - return nil -} - -func (iter *Iterator) curPushNextStack(cur *Node) { - next := 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) // 入栈 用于回溯 - } - } -} - -func (iter *Iterator) getPrevUp(cur *Node) *Node { - for cur.parent != nil { - if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序 - return cur.parent - } - cur = cur.parent - } - return nil -} - -func (iter *Iterator) curPushPrevStack(cur *Node) { - prev := cur.children[1] - - if prev != nil { - iter.tstack.Push(prev) - for prev.children[0] != nil { - prev = prev.children[0] - iter.tstack.Push(prev) - } - } -} diff --git a/sbt/sbt.go b/sbt/sbt.go deleted file mode 100644 index 2ded8e4..0000000 --- a/sbt/sbt.go +++ /dev/null @@ -1,904 +0,0 @@ -package avlindex - -import ( - "log" - - "github.com/davecgh/go-spew/spew" - - "github.com/emirpasic/gods/utils" -) - -type Node struct { - children [2]*Node - parent *Node - size int - value interface{} -} - -func (n *Node) String() string { - if n == nil { - return "nil" - } - - p := "nil" - if n.parent != nil { - p = spew.Sprint(n.parent.value) - } - return spew.Sprint(n.value) + "(" + p + "|" + spew.Sprint(n.size) + ")" -} - -type Tree struct { - root *Node - comparator utils.Comparator -} - -func New(comparator utils.Comparator) *Tree { - return &Tree{comparator: comparator} -} - -func (avl *Tree) String() string { - str := "AVLTree\n" - if avl.root == nil { - return str + "nil" - } - output(avl.root, "", true, &str) - return str -} - -func (avl *Tree) Iterator() *Iterator { - return initIterator(avl) -} - -func (avl *Tree) Size() int { - if avl.root == nil { - return 0 - } - return avl.root.size -} - -func (avl *Tree) indexNode(idx int) *Node { - cur := avl.root - if idx >= 0 { - for cur != nil { - ls := getSize(cur.children[0]) - if idx == ls { - return cur - } else if idx < ls { - cur = cur.children[0] - } else { - idx = idx - ls - 1 - cur = cur.children[1] - } - } - } else { - idx = -idx - 1 - for cur != nil { - rs := getSize(cur.children[1]) - if idx == rs { - return cur - } else if idx < rs { - cur = cur.children[1] - } else { - idx = idx - rs - 1 - cur = cur.children[0] - } - } - } - return nil -} - -func (avl *Tree) Index(idx int) (interface{}, bool) { - n := avl.indexNode(idx) - if n != nil { - return n.value, true - } - return nil, false -} - -func (avl *Tree) RemoveIndex(idx int) bool { - n := avl.indexNode(idx) - if n != nil { - avl.removeNode(n) - return true - } - return false -} - -func (avl *Tree) removeNode(n *Node) { - if avl.root.size == 1 { - avl.root = nil - // return n - return - } - - ls, rs := getChildrenSize(n) - if ls == 0 && rs == 0 { - p := n.parent - p.children[getRelationship(n)] = nil - avl.fixRemoveHeight(p) - // return n - return - } - - var cur *Node - if ls > rs { - cur = n.children[0] - for cur.children[1] != nil { - cur = cur.children[1] - } - - cleft := cur.children[0] - cur.parent.children[getRelationship(cur)] = cleft - if cleft != nil { - cleft.parent = cur.parent - } - - } else { - cur = n.children[1] - for cur.children[0] != nil { - cur = cur.children[0] - } - - cright := cur.children[1] - cur.parent.children[getRelationship(cur)] = cright - - if cright != nil { - cright.parent = cur.parent - } - } - - cparent := cur.parent - // 修改为interface 交换 - n.value, cur.value = cur.value, n.value - - // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 - if cparent == n { - avl.fixRemoveHeight(n) - } else { - avl.fixRemoveHeight(cparent) - } - - // return cur - return -} - -func (avl *Tree) Remove(key interface{}) bool { - - if n, ok := avl.GetNode(key); ok { - avl.removeNode(n) - return true - } - // return nil - return false -} - -// Values 返回先序遍历的值 -func (avl *Tree) Values() []interface{} { - mszie := 0 - if avl.root != nil { - mszie = avl.root.size - } - result := make([]interface{}, 0, mszie) - avl.Traversal(func(v interface{}) bool { - result = append(result, v) - return true - }, LDR) - return result -} - -func (avl *Tree) IndexRange(idx1, idx2 int) (result []interface{}, ok bool) { // 0 -1 - - if idx1^idx2 < 0 { - if idx1 < 0 { - idx1 = avl.root.size + idx1 - 1 - } else { - idx2 = avl.root.size + idx2 - 1 - } - } - - if idx1 > idx2 { - ok = true - if idx1 >= avl.root.size { - idx1 = avl.root.size - 1 - ok = false - } - - n := avl.indexNode(idx1) - iter := NewIterator(n) - result = make([]interface{}, 0, idx1-idx2) - for i := idx2; i <= idx1; i++ { - if iter.Next() { - result = append(result, iter.Value()) - } else { - ok = false - return - } - } - - return - - } else { - ok = true - if idx2 >= avl.root.size { - idx2 = avl.root.size - 1 - ok = false - } - - if n := avl.indexNode(idx1); n != nil { - iter := NewIterator(n) - result = make([]interface{}, 0, idx2-idx1) - for i := idx1; i <= idx2; i++ { - if iter.Prev() { - result = append(result, iter.Value()) - } else { - ok = false - return - } - } - - return - } - - } - - return nil, false -} - -func (avl *Tree) Get(key interface{}) (interface{}, bool) { - n, ok := avl.GetNode(key) - if ok { - return n.value, true - } - return n, false -} - -func (avl *Tree) GetAround(key interface{}) (result [3]interface{}) { - an := avl.GetAroundNode(key) - for i, n := range an { - if n != nil { - result[i] = n.value - } - } - return -} - -func (avl *Tree) GetAroundNode(value interface{}) (result [3]*Node) { - - if cur, ok := avl.GetNode(value); ok { - - var iter *Iterator - - iter = NewIterator(cur) - iter.curPushPrevStack(iter.up) - iter.up = iter.getPrevUp(iter.up) - - if v, ok := iter.tstack.Pop(); ok { - result[0] = v.(*Node) - // iter.curPushPrevStack(iter.cur) - } else { - result[0] = iter.up - } - - iter = NewIterator(cur) - iter.curPushNextStack(iter.up) - iter.up = iter.getNextUp(iter.up) - - if v, ok := iter.tstack.Pop(); ok { - result[2] = v.(*Node) - // iter.curPushNextStack(iter.cur) - } else { - result[2] = iter.up - } - - result[1] = cur - } - return -} -func (avl *Tree) GetNode(value interface{}) (*Node, bool) { - - for n := avl.root; n != nil; { - switch c := avl.comparator(value, n.value); c { - case -1: - n = n.children[0] - case 1: - n = n.children[1] - case 0: - return n, true - default: - panic("Get comparator only is allowed in -1, 0, 1") - } - } - return nil, false -} - -func (avl *Tree) Put(value interface{}) { - - node := &Node{value: value, size: 1} - if avl.root == nil { - avl.root = node - return - } - - cur := avl.root - parent := cur.parent - child := -1 - - for { - - if cur == nil { - parent.children[child] = node - node.parent = parent - - fixed := parent.parent - fsize := getSize(fixed) - if fsize == 3 { - lefts, rigths := getChildrenSize(fixed) - avl.fix3PutHeight(fixed, lefts, rigths) - } - return - } - - if cur.size > 9 { - ls, rs := cur.children[0].size, cur.children[1].size - factor := cur.size / 10 // or factor = 1 - if rs >= ls*2+factor || ls >= rs*2+factor { - avl.fixPutHeight(cur, ls, rs) - } - } - - cur.size++ - parent = cur - c := avl.comparator(value, cur.value) - child = (c + 2) / 2 - cur = cur.children[child] - } -} - -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 遍历的方法 -func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...interface{}) { - if avl.root == nil { - return - } - - method := LDR - if len(traversalMethod) != 0 { - method = traversalMethod[0].(TraversalMethod) - } - - switch method { - case DLR: - 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(avl.root) - case LDR: - var traverasl func(cur *Node) bool - traverasl = func(cur *Node) bool { - if cur == nil { - return true - } - if !traverasl(cur.children[0]) { - log.Println(cur) - return false - } - if !every(cur.value) { - return false - } - if !traverasl(cur.children[1]) { - return false - } - return true - } - traverasl(avl.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(avl.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(avl.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(avl.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(avl.root) - } -} - -func (avl *Tree) lrrotate3(cur *Node) { - const l = 1 - const r = 0 - - movparent := cur.children[l] - mov := movparent.children[r] - - mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - - cur.children[r] = mov - mov.parent = cur - - cur.children[l] = movparent - movparent.children[r] = nil - - cur.children[r] = mov - mov.parent = cur - - // cur.size = 3 - // cur.children[r].size = 1 - cur.children[l].size = 1 -} - -func (avl *Tree) lrrotate(cur *Node) { - - const l = 1 - const r = 0 - - movparent := cur.children[l] - mov := movparent.children[r] - - mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - - if mov.children[l] != nil { - movparent.children[r] = mov.children[l] - movparent.children[r].parent = movparent - //movparent.children[r].child = l - } else { - movparent.children[r] = nil - } - - if mov.children[r] != nil { - mov.children[l] = mov.children[r] - //mov.children[l].child = l - } 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.parent = cur - - // cur.size = 3 - // cur.children[0].size = 1 - // cur.children[1].size = 1 - - 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) rlrotate3(cur *Node) { - const l = 0 - const r = 1 - - movparent := cur.children[l] - mov := movparent.children[r] - - mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - - cur.children[r] = mov - mov.parent = cur - - cur.children[l] = movparent - movparent.children[r] = nil - - cur.children[r] = mov - mov.parent = cur - - // cur.size = 3 - // cur.children[r].size = 1 - cur.children[l].size = 1 -} - -func (avl *Tree) rlrotate(cur *Node) { - - const l = 0 - const r = 1 - - movparent := cur.children[l] - mov := movparent.children[r] - - mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - - if mov.children[l] != nil { - movparent.children[r] = mov.children[l] - movparent.children[r].parent = movparent - } else { - movparent.children[r] = nil - } - - 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.parent = cur - - movparent.size = getChildrenSumSize(movparent) + 1 - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 1 -} - -func (avl *Tree) rrotate3(cur *Node) { - const l = 0 - const r = 1 - // 1 right 0 left - mov := cur.children[l] - - mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - - cur.children[r] = mov - mov.size = 1 - - cur.children[l] = mov.children[l] - cur.children[l].parent = cur - - mov.children[l] = nil - - mov.size = 1 -} - -func (avl *Tree) rrotate(cur *Node) { - - const l = 0 - const r = 1 - // 1 right 0 left - mov := cur.children[l] - - // lsize, rsize := getChildrenHeight(cur) - // movrsize := getSize(mov.children[r]) - - 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 - - // cur.size = 3 - // cur.children[0].size = 1 - // cur.children[1].size = 1 - - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 1 - // cur.height = getMaxChildrenHeight(cur) + 1 -} - -func (avl *Tree) lrotate3(cur *Node) { - const l = 1 - const r = 0 - // 1 right 0 left - mov := cur.children[l] - - mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 - - cur.children[r] = mov - mov.size = 1 - - cur.children[l] = mov.children[l] - cur.children[l].parent = cur - - mov.children[l] = nil - - mov.size = 1 -} - -func (avl *Tree) lrotate(cur *Node) { - - const l = 1 - const r = 0 - // 1 right 0 left - mov := cur.children[l] - - // lsize, rsize := getChildrenHeight(cur) - // movrsize := getSize(mov.children[r]) - - 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 - - // cur.size = 3 - // cur.children[0].size = 1 - // cur.children[1].size = 1 - - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 1 -} - -func getChildrenSumSize(cur *Node) int { - return getSize(cur.children[0]) + getSize(cur.children[1]) -} - -func getChildrenSize(cur *Node) (int, int) { - return getSize(cur.children[0]), getSize(cur.children[1]) -} - -func getSize(cur *Node) int { - if cur == nil { - return 0 - } - return cur.size -} - -func (avl *Tree) fixRemoveHeight(cur *Node) { - for cur != nil { - cur.size-- - if cur.size > 9 { - ls, rs := cur.children[0].size, cur.children[1].size - if rs >= ls*2 || ls >= rs*2 { - avl.fixPutHeight(cur, ls, rs) - } - } - cur = cur.parent - } -} - -func (avl *Tree) fix3PutHeight(cur *Node, lefts, rigths int) { - if lefts > rigths { - l := cur.children[0] - llsize, lrsize := getChildrenSize(l) - if lrsize > llsize { - avl.rlrotate3(cur) - } else { - avl.rrotate3(cur) - } - } else { - r := cur.children[1] - rlsize, rrsize := getChildrenSize(r) - if rlsize > rrsize { - avl.lrrotate3(cur) - } else { - avl.lrotate3(cur) - } - } -} - -func (avl *Tree) fixPutHeight(cur *Node, lefts, rigths int) { - if lefts > rigths { - l := cur.children[0] - llsize, lrsize := getChildrenSize(l) - if lrsize > llsize { - avl.rlrotate(cur) - } else { - avl.rrotate(cur) - } - } else { - r := cur.children[1] - rlsize, rrsize := getChildrenSize(r) - if rlsize > rrsize { - avl.lrrotate(cur) - } else { - avl.lrotate(cur) - } - } -} - -func output(node *Node, prefix string, isTail bool, str *string) { - - if node.children[1] != nil { - newPrefix := prefix - if isTail { - newPrefix += "│ " - } else { - newPrefix += " " - } - output(node.children[1], newPrefix, false, str) - } - *str += prefix - if isTail { - *str += "└── " - } else { - *str += "┌── " - } - - *str += spew.Sprint(node.value) + "\n" - - if node.children[0] != nil { - newPrefix := prefix - if isTail { - newPrefix += " " - } else { - newPrefix += "│ " - } - output(node.children[0], newPrefix, true, str) - } - -} - -func outputfordebug(node *Node, prefix string, isTail bool, str *string) { - - if node.children[1] != nil { - newPrefix := prefix - if isTail { - newPrefix += "│ " - } else { - newPrefix += " " - } - outputfordebug(node.children[1], newPrefix, false, str) - } - *str += prefix - if isTail { - *str += "└── " - } else { - *str += "┌── " - } - - suffix := "(" - parentv := "" - if node.parent == nil { - parentv = "nil" - } else { - parentv = spew.Sprint(node.parent.value) - } - suffix += parentv + "|" + spew.Sprint(node.size) + ")" - *str += spew.Sprint(node.value) + suffix + "\n" - - if node.children[0] != nil { - newPrefix := prefix - if isTail { - newPrefix += " " - } else { - newPrefix += "│ " - } - outputfordebug(node.children[0], newPrefix, true, str) - } -} - -func (avl *Tree) debugString() string { - str := "AVLTree\n" - if avl.root == nil { - return str + "nil" - } - outputfordebug(avl.root, "", true, &str) - return str -} diff --git a/sbt/sbt_test.go b/sbt/sbt_test.go deleted file mode 100644 index d856ca8..0000000 --- a/sbt/sbt_test.go +++ /dev/null @@ -1,649 +0,0 @@ -package avlindex - -import ( - "bytes" - "encoding/gob" - "io/ioutil" - "log" - "os" - "testing" - - "github.com/huandu/skiplist" - - "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 = 1000000 -const NumberMax = 50000000 - -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 - - // for i := 0; len(l) < 1000; i++ { - // v := randomdata.Number(0, 65535) - // l = append(l, v) - // } - - //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 { - log.Println(err) - } - var l []int - decoder := gob.NewDecoder(bytes.NewReader(data)) - decoder.Decode(&l) - return l -} - -func TestIterator(t *testing.T) { - // avl := New(utils.IntComparator) - // for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 40, 50, 3, 40, 40, 40, 15} { - // avl.Put(v) - // } - // t.Error(avl.Values()) - // t.Error(avl.debugString()) - -} - -func TestIndexRange(t *testing.T) { - tree := New(utils.IntComparator) - 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) - } - // [3 7 14 14 14 15 16 17 20 21 30 40 40 40 40 50] - // t.Error(tree.Values(), tree.Size()) - - var result string - result = spew.Sprint(tree.IndexRange(0, 5)) - if result != "[3 7 14 14 14 15] true" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(2, 5)) - if result != "[14 14 14 15] true" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(10, 100)) - if result != "[30 40 40 40 40 50] false" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(15, 0)) // size = 16, index max = 15 - if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] true" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(16, 0)) // size = 16, index max = 15 - if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] false" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(5, 1)) // size = 16, index max = 15 - if result != "[15 14 14 14 7] true" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(-1, -5)) // size = 16, index max = 15 - if result != "[50 40 40 40 40] true" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(-1, -16)) // size = 16, index max = 0 - 15 (-1,-16) - if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] true" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(-1, -17)) // size = 16, index max = 0 - 15 (-1,-16) - if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] false" { - t.Error(result) - } - - result = spew.Sprint(tree.IndexRange(-5, -1)) // size = 16, index max = 0 - 15 (-1,-16) - if result != "[40 40 40 40 50] true" { - t.Error(result) - } -} - -func TestGetAround(t *testing.T) { - avl := New(utils.IntComparator) - for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} { - avl.Put(v) - } - - var Result string - - Result = spew.Sprint(avl.GetAround(3)) - if Result != "[7 3 ]" { - t.Error("avl.GetAround(3)) is error", Result) - } - - Result = spew.Sprint(avl.GetAround(40)) - if Result != "[40 40 30]" { - t.Error("avl.GetAround(40)) is error", Result) - } - - Result = spew.Sprint(avl.GetAround(50)) - if Result != "[ 50 40]" { - t.Error("avl.GetAround(50)) is error", Result) - } -} - -// // for test error case - -func TestPutComparatorRandom(t *testing.T) { - - for n := 0; n < 300000; n++ { - avl := New(utils.IntComparator) - 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) + "," - avl.Put(v) - godsavl.Put(v, v) - } - } - - s1 := spew.Sprint(avl.Values()) - s2 := spew.Sprint(godsavl.Values()) - - if s1 != s2 { - t.Error(godsavl.String()) - t.Error(avl.debugString()) - t.Error(content, n) - break - } - } -} - -func TestGet(t *testing.T) { - avl := New(utils.IntComparator) - for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - avl.Put(v) - } - - for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { - v, ok := avl.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) - } -} - -func TestTravalsal(t *testing.T) { - tree := New(utils.IntComparator) - - l := loadTestData() - N := len(l) - for i := 0; i < N; i++ { - tree.Put(l[i]) - } - - i := 0 - var result []interface{} - tree.Traversal(func(v interface{}) bool { - result = append(result, v) - i++ - if i >= 10 { - return false - } - return true - }) - t.Error(result) -} - -func TestRemoveAll(t *testing.T) { -ALL: - for c := 0; c < 5000; c++ { - avl := New(utils.IntComparator) - gods := avltree.NewWithIntComparator() - var l []int - m := make(map[int]int) - - for i := 0; len(l) < 10; i++ { - v := randomdata.Number(0, 100000) - if _, ok := m[v]; !ok { - m[v] = v - l = append(l, v) - avl.Put(v) - gods.Put(v, v) - } - } - - for i := 0; i < 10; i++ { - - avl.Remove(l[i]) - gods.Remove(l[i]) - - s1 := spew.Sprint(avl.Values()) - s2 := spew.Sprint(gods.Values()) - if s1 != s2 { - t.Error("avl remove error", "avlsize = ", avl.Size()) - t.Error(avl.root, i, l[i]) - t.Error(s1) - t.Error(s2) - break ALL - } - } - } -} - -func TestRemove(t *testing.T) { - -ALL: - for N := 0; N < 50000; N++ { - avl := New(utils.IntComparator) - gods := avltree.NewWithIntComparator() - - var l []int - m := make(map[int]int) - - for i := 0; len(l) < 10; i++ { - v := randomdata.Number(0, 100) - if _, ok := m[v]; !ok { - l = append(l, v) - m[v] = v - avl.Put(v) - gods.Put(v, v) - } - } - - src1 := avl.String() - src2 := gods.String() - - for i := 0; i < 10; i++ { - avl.Remove(l[i]) - gods.Remove(l[i]) - if avl.root != nil && spew.Sprint(gods.Values()) != spew.Sprint(avl.Values()) { - // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { - t.Error(src1) - t.Error(src2) - t.Error(avl.debugString()) - t.Error(gods.String()) - t.Error(l[i]) - // t.Error(avl.TraversalDepth(-1)) - // t.Error(gods.Values()) - break ALL - } - } - } -} - -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 { - e := sl.Get(v) - var result [50]interface{} - for i := 0; i < 50 && e != nil; i++ { - result[i] = e.Value - e = e.Next() - } - } - } -} - -func BenchmarkGetRange(b *testing.B) { - tree := New(utils.IntComparator) - l := loadTestData() - b.N = len(l) - - for _, v := range l { - tree.Put(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 BenchmarkSkipListSet(b *testing.B) { - sl := skiplist.New(skiplist.Int) - l := loadTestData() - - execCount := 50 - b.N = len(l) * execCount - - for i := 0; i < execCount; i++ { - for _, v := range l { - sl.Set(v, v) - } - } - -} - -func BenchmarkIterator(b *testing.B) { - tree := New(utils.IntComparator) - - l := loadTestData() - b.N = len(l) - - for _, v := range l { - tree.Put(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(utils.IntComparator) - - l := loadTestData() - - b.N = len(l) - for _, v := range l { - tree.Put(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(utils.IntComparator) - - l := loadTestData() - b.N = len(l) - for i := 0; i < b.N; i++ { - tree.Put(l[i]) - } - - b.ResetTimer() - b.StartTimer() - - execCount := 50 - 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 := 50 - 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 := 50 - 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++ { - avl := New(utils.IntComparator) - for _, v := range l { - avl.Put(v) - } - } -} - -func TestPutStable(t *testing.T) { - - // l := []int{14, 18, 20, 21, 22, 23, 19} - var l []int - for i := 0; len(l) < 10; i++ { - l = append(l, randomdata.Number(0, 65)) - } - - avl := New(utils.IntComparator) - for _, v := range l { - avl.Put(v) - t.Error(avl.debugString(), v) - } - t.Error(avl.Values()) - for _, v := range []int{10, 0, 9, 5, -11, -10, -1, -5} { - t.Error(avl.Index(v)) - } - - avl.RemoveIndex(4) - t.Error(avl.Index(4)) - t.Error(avl.Values()) - t.Error(avl.debugString()) - // t.Error(len(l), avl.debugString(), "\n", "-----------") // 3 6(4) - -} - -func BenchmarkIndex(b *testing.B) { - tree := New(utils.IntComparator) - - l := loadTestData() - b.N = len(l) - for i := 0; i < b.N; i++ { - tree.Put(l[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(utils.IntComparator) - - l := loadTestData() - b.N = len(l) - for i := 0; i < b.N; i++ { - tree.Put(l[i]) - } - - b.ResetTimer() - b.StartTimer() - - execCount := 50 - 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) { - tree := redblacktree.NewWithIntComparator() - - l := loadTestData() - - b.ResetTimer() - b.StartTimer() - - b.N = len(l) - 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) - } -} diff --git a/vbtkey/vbtkey.go b/vbtkey/vbtkey.go index feb4e6e..9a486c6 100644 --- a/vbtkey/vbtkey.go +++ b/vbtkey/vbtkey.go @@ -2,8 +2,6 @@ package avlindex import ( "github.com/davecgh/go-spew/spew" - - "github.com/emirpasic/gods/utils" ) type Node struct { @@ -28,10 +26,10 @@ func (n *Node) String() string { type Tree struct { root *Node - comparator utils.Comparator + comparator comparator.Comparator } -func New(comparator utils.Comparator) *Tree { +func New(comparator comparator.Comparator) *Tree { return &Tree{comparator: comparator} }