diff --git a/avlkey/avl_test.go b/avlkey/avl_test.go deleted file mode 100644 index 6cc2757..0000000 --- a/avlkey/avl_test.go +++ /dev/null @@ -1,503 +0,0 @@ -package avl - -import ( - "log" - "testing" - - "github.com/emirpasic/gods/maps/hashmap" - "github.com/emirpasic/gods/trees/redblacktree" - - "github.com/emirpasic/gods/trees/avltree" - - "github.com/davecgh/go-spew/spew" - - "github.com/Pallinder/go-randomdata" - - "github.com/emirpasic/gods/utils" -) - -func TestRotate(t *testing.T) { - avl := New(utils.IntComparator) - - content := "" - for i := 0; i < 10; i++ { - v := randomdata.Number(0, 1000) - content += spew.Sprint(v) + " " - avl.Put(v) - } - - t.Error(content) - src := avl.String() - t.Error(src) - - lsrc := avl.String() - t.Error(lsrc) - // rrotate(&avl.root) - rsrc := avl.String() - t.Error(rsrc) - - if src == rsrc { - t.Error("src == rsrc") - } -} - -func TestIterator(t *testing.T) { - avl := New(utils.IntComparator) - for _, v := range []int{1, 2, 7, 4, 5, 6, 7, 14, 15, 20, 30, 21, 3} { - // t.Error(v) - avl.Put(v) - - } - t.Error(avl.TraversalDepth(1)) - t.Error(avl.debugString()) - iter := avl.Iterator() - - for iter.Prev() { - t.Error(iter.Value()) - } - t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value()) - - for iter.Next() { - t.Error(iter.Value()) - } - t.Error("next == false", iter.Value(), iter.Next(), iter.Value()) - - for iter.Prev() { - t.Error(iter.Value()) - } - t.Error("prev == false", iter.Value()) - - for i := 0; iter.Next(); i++ { - t.Error(iter.Value()) - if i >= 7 { - break - } - } - t.Error("next == false", iter.Value()) - - for iter.Prev() { - t.Error(iter.Value()) - } - t.Error("prev == false", iter.Value()) -} - -func TestGetAround(t *testing.T) { - avl := New(utils.IntComparator) - for _, v := range []int{7, 14, 15, 20, 30, 21, 40, 40, 50, 3, 40, 40, 40} { - t.Error(v) - avl.Put(v) - t.Error(avl.debugString()) - } - t.Error(avl.TraversalDepth(1)) - t.Error(avl.GetAroundNode(40)) - t.Error(avl.GetAround(40)) -} - -func TestPutStable(t *testing.T) { - avl := New(utils.IntComparator) - for _, v := range []int{7, 14, 15, 20, 30, 21} { - t.Error(v) - avl.Put(v) - t.Error(avl.debugString()) - } - // avl = New(utils.IntComparator) - // for _, v := range []int{88, 77, 80} { - // avl.Put(v) - // t.Error(avl.String()) - // } -} - -func TestDiffPutRandom(t *testing.T) { - avl := New(utils.IntComparator) - godsavl := avltree.NewWithIntComparator() - - content := "" - m := make(map[int]int) - for i := 0; len(m) < 10; i++ { - v := randomdata.Number(0, 10000) - if _, ok := m[v]; !ok { - m[v] = v - content += spew.Sprint(v) + " " - t.Error(v) - avl.Put(v) - t.Error(avl.String()) - godsavl.Put(v, v) - } - } - t.Error(godsavl.String()) -} - -func TestPutComparatorRandom(t *testing.T) { - - for n := 0; n < 1000000; 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) + " " - // t.Error(v) - avl.Put(v) - // t.Error(avl.String()) - godsavl.Put(v, v) - } - } - - if avl.String() != godsavl.String() { - t.Error(godsavl.String()) - t.Error(avl.String()) - t.Error(content, n) - break - } - } - - // t.Error(content) - // t.Error(avl.String()) - // t.Error(godsavl.String()) - // t.Error(avl.String() == godsavl.String()) - -} - -func TestGet(t *testing.T) { - avl := New(utils.IntComparator) - for i := 0; i < 15; i++ { - avl.Put(randomdata.Number(0, 1000)) - } - t.Error(avl.String()) - t.Error(avl.Get(500)) -} - -func TestRemoveAll(t *testing.T) { - - for c := 0; c < 10000; c++ { - // f, _ := os.OpenFile("./out.log", os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0666) - // log.SetOutput(f) - - avl := New(utils.IntComparator) - var l []int - for i := 0; i < 100; i++ { - v := randomdata.Number(0, 100000) - l = append(l, v) - avl.Put(v) - } - // defer func() { - // if err := recover(); err != nil { - // panic(avl.String()) - // } - // }() - // log.Println(avl.TraversalBreadth()) - for i := 0; i < 100; i++ { - // log.Println(l[i]) - // log.Println(avl.debugString()) - avl.Remove(l[i]) - } - } -} - -func TestRemove(t *testing.T) { - - // avl := New(utils.IntComparator) - - // var l []int - // for _, v := range []int{86, 97, 9, 61, 37, 45, 97, 43, 95, 8} { - // l = append(l, v) - // avl.Put(v) - // } - - // for i := 0; i < len(l); i++ { - // // log.Println(i) - // log.Println("begin", l[i], avl.debugString()) - // avl.Remove(l[i]) - // log.Println("end", l[i], avl.debugString()) - // } - -ALL: - for N := 0; N < 500000; 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 spew.Sprint(gods.Values()) != spew.Sprint(avl.TraversalDepth(-1)) && avl.size != 0 { - // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { - t.Error(src1) - t.Error(src2) - t.Error(avl.debugString()) - t.Error(gods.String()) - t.Error(l[i]) - // t.Error(avl.TraversalDepth(-1)) - // t.Error(gods.Values()) - break ALL - - } - } - } -} - -const CompartorSize = 300000 -const NumberMax = 60000000 - -func BenchmarkIterator(b *testing.B) { - avl := New(utils.IntComparator) - b.N = CompartorSize - - for i := 0; i < b.N; i++ { - v := randomdata.Number(0, NumberMax) - avl.Put(v) - } - - b.ResetTimer() - b.StartTimer() - iter := avl.Iterator() - for iter.Next() { - - } - - for iter.Prev() { - - } - - for iter.Next() { - - } - -} - -func BenchmarkGodsIterator(b *testing.B) { - avl := avltree.NewWithIntComparator() - b.N = CompartorSize - - for i := 0; i < b.N; i++ { - v := randomdata.Number(0, NumberMax) - avl.Put(v, i) - } - - b.ResetTimer() - b.StartTimer() - iter := avl.Iterator() - for iter.Next() { - - } - - for iter.Prev() { - - } - - for iter.Next() { - - } - -} - -func BenchmarkRemove(b *testing.B) { - - avl := New(utils.IntComparator) - b.N = CompartorSize - - var l []int - for i := 0; i < b.N; i++ { - v := randomdata.Number(0, NumberMax) - l = append(l, v) - avl.Put(v) - } - - b.ResetTimer() - b.StartTimer() - - for i := 0; i < b.N; i++ { - avl.Remove(l[i]) - } -} - -func BenchmarkGodsRemove(b *testing.B) { - avl := avltree.NewWithIntComparator() - b.N = CompartorSize - - var l []int - for i := 0; i < b.N; i++ { - v := randomdata.Number(0, NumberMax) - l = append(l, v) - avl.Put(v, v) - } - - b.ResetTimer() - b.StartTimer() - - for i := 0; i < b.N; i++ { - avl.Remove(l[i]) - } -} - -func BenchmarkGoGet(b *testing.B) { - avl := make(map[int]int) - - b.N = CompartorSize - for i := 0; i < b.N; i++ { - avl[randomdata.Number(0, NumberMax)] = i - } - - b.ResetTimer() - b.StartTimer() - b.N = CompartorSize - - var v int - var ok bool - for i := 0; i < b.N; i++ { - v, ok = avl[randomdata.Number(0, NumberMax)] - } - - if ok && v == 1 { - v = 1 - } -} - -func BenchmarkGet(b *testing.B) { - - avl := New(utils.IntComparator) - - b.N = CompartorSize - for i := 0; i < b.N/2; i++ { - avl.Put(randomdata.Number(0, NumberMax)) - } - - b.ResetTimer() - b.StartTimer() - for i := 0; i < b.N; i++ { - avl.Get(randomdata.Number(0, NumberMax)) - } -} - -func BenchmarkGodsRBGet(b *testing.B) { - rb := redblacktree.NewWithIntComparator() - - b.N = CompartorSize - for i := 0; i < b.N/2; i++ { - rb.Put(randomdata.Number(0, NumberMax), i) - } - - b.ResetTimer() - b.StartTimer() - for i := 0; i < b.N; i++ { - rb.Get(randomdata.Number(0, NumberMax)) - } -} - -func BenchmarkGodsAvlGet(b *testing.B) { - rb := avltree.NewWithIntComparator() - - b.N = CompartorSize - for i := 0; i < b.N/2; i++ { - rb.Put(randomdata.Number(0, NumberMax), i) - } - - b.ResetTimer() - b.StartTimer() - for i := 0; i < b.N; i++ { - rb.Get(randomdata.Number(0, NumberMax)) - } -} - -func BenchmarkGoPut(b *testing.B) { - avl := make(map[int]int) - - for i := 0; i < 100000; i++ { - avl[randomdata.Number(0, NumberMax)] = i - } - - b.ResetTimer() - b.StartTimer() - b.N = CompartorSize - - for i := 0; i < b.N; i++ { - avl[randomdata.Number(0, NumberMax)] = i - } - - log.Println(avl[12]) -} - -func BenchmarkGodsHashmap(b *testing.B) { - avl := hashmap.New() - - b.N = CompartorSize * 10 - for i := 0; i < b.N; i++ { - avl.Put(randomdata.Number(0, NumberMax), i) - } - - // b.ResetTimer() - // b.StartTimer() - // b.N = CompartorSize - - // for i := 0; i < b.N; i++ { - // avl[randomdata.Number(0, NumberMax)] = i - // } -} - -func BenchmarkPut(b *testing.B) { - avl := New(utils.IntComparator) - - for i := 0; i < 100000; i++ { - avl.Put(randomdata.Number(0, NumberMax)) - } - - b.ResetTimer() - b.StartTimer() - b.N = CompartorSize - for i := 0; i < b.N; i++ { - avl.Put(randomdata.Number(0, NumberMax)) - } - -} - -func BenchmarkGodsRBPut(b *testing.B) { - rb := redblacktree.NewWithIntComparator() - - for i := 0; i < 100000; i++ { - rb.Put(randomdata.Number(0, NumberMax), i) - } - - b.ResetTimer() - b.StartTimer() - - b.N = CompartorSize - for i := 0; i < b.N; i++ { - rb.Put(randomdata.Number(0, NumberMax), i) - } - -} - -func BenchmarkGodsPut(b *testing.B) { - avl := avltree.NewWithIntComparator() - - for i := 0; i < 100000; i++ { - avl.Put(randomdata.Number(0, NumberMax), i) - } - - b.ResetTimer() - b.StartTimer() - - b.N = CompartorSize - for i := 0; i < b.N; i++ { - avl.Put(randomdata.Number(0, NumberMax), i) - } -} diff --git a/avlkey/avl.go b/avlkey/avlkey.go similarity index 53% rename from avlkey/avl.go rename to avlkey/avlkey.go index 0329ed5..b0f7d16 100644 --- a/avlkey/avl.go +++ b/avlkey/avlkey.go @@ -1,6 +1,8 @@ package avl import ( + "log" + "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/utils" @@ -61,68 +63,71 @@ func (avl *AVL) Size() int { return avl.size } -func (avl *AVL) Remove(v interface{}) *Node { +// func (avl *AVL) Remove(key interface{}) *Node { - if n, ok := avl.GetNode(v); ok { +// if n, ok := avl.GetNode(key); ok { - avl.size-- - if avl.size == 0 { - avl.root = nil - return n - } +// avl.size-- +// if avl.size == 0 { +// avl.root = nil +// return n +// } - left := getHeight(n.children[0]) - right := getHeight(n.children[1]) +// left := getHeight(n.children[0]) +// right := getHeight(n.children[1]) - if left == -1 && right == -1 { - p := n.parent - p.children[n.child] = nil - avl.fixRemoveHeight(p) - return n - } +// if left == -1 && right == -1 { +// p := n.parent +// p.children[n.child] = nil +// avl.fixRemoveHeight(p) +// return n +// } - var cur *Node - if left > right { - cur = n.children[0] - for cur.children[1] != nil { - cur = cur.children[1] - } +// var cur *Node +// if left > right { +// cur = n.children[0] +// for cur.children[1] != nil { +// cur = cur.children[1] +// } - cleft := cur.children[0] - cur.parent.children[cur.child] = cleft - if cleft != nil { - cleft.child = cur.child - cleft.parent = cur.parent - } +// cleft := cur.children[0] +// cur.parent.children[cur.child] = cleft +// if cleft != nil { +// cleft.child = cur.child +// cleft.parent = cur.parent +// } - } else { - cur = n.children[1] - for cur.children[0] != nil { - cur = cur.children[0] - } +// } else { +// cur = n.children[1] +// for cur.children[0] != nil { +// cur = cur.children[0] +// } - cright := cur.children[1] - cur.parent.children[cur.child] = cright - if cright != nil { - cright.child = cur.child - cright.parent = cur.parent - } - } +// cright := cur.children[1] +// cur.parent.children[cur.child] = cright +// if cright != nil { +// cright.child = cur.child +// cright.parent = cur.parent +// } +// } - cparent := cur.parent - avl.replace(n, cur) - // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 - if cparent == n { - avl.fixRemoveHeight(cur) - } else { - avl.fixRemoveHeight(cparent) - } +// cparent := cur.parent +// // avl.replace(n, cur) 修改为interface +// temp := n.value +// n.value = cur.value +// cur.value = temp +// // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度 +// if cparent == n { +// avl.fixRemoveHeight(n) +// } else { +// avl.fixRemoveHeight(cparent) +// } - return n - } +// return cur +// } - return nil -} +// return nil +// } func (avl *AVL) Get(v interface{}) (interface{}, bool) { n, ok := avl.GetNode(v) @@ -132,8 +137,8 @@ func (avl *AVL) Get(v interface{}) (interface{}, bool) { return n, false } -func (avl *AVL) GetAround(v interface{}) (result [3]interface{}) { - an := avl.GetAroundNode(v) +func (avl *AVL) GetAround(key interface{}) (result [3]interface{}) { + an := avl.GetAroundNode(key) for i, n := range an { if n.value != nil { result[i] = n.value @@ -142,7 +147,7 @@ func (avl *AVL) GetAround(v interface{}) (result [3]interface{}) { return } -func (avl *AVL) GetAroundNode(v interface{}) (result [3]*Node) { +func (avl *AVL) GetAroundNode(key interface{}) (result [3]*Node) { n := avl.root for { @@ -152,7 +157,7 @@ func (avl *AVL) GetAroundNode(v interface{}) (result [3]*Node) { } lastc := 0 - switch c := avl.comparator(v, n.value); c { + switch c := avl.comparator(key, n.key); c { case -1: if c != -lastc { result[0] = n @@ -195,11 +200,11 @@ func (avl *AVL) GetAroundNode(v interface{}) (result [3]*Node) { } } -func (avl *AVL) GetNode(v interface{}) (*Node, bool) { +func (avl *AVL) GetNode(key interface{}) (*Node, bool) { n := avl.root for n != nil { - switch c := avl.comparator(v, n.value); c { + switch c := avl.comparator(key, n.key); c { case -1: n = n.children[0] case 1: @@ -241,6 +246,9 @@ func (avl *AVL) Put(key, value interface{}) { parent = cur c := avl.comparator(node.key, cur.key) + if node.key.(int) == 34293 { + log.Println(c, node.key, cur.key) + } if c > -1 { // right child = 1 cur = cur.children[child] @@ -252,43 +260,6 @@ func (avl *AVL) Put(key, value interface{}) { } -func (avl *AVL) replace(old *Node, newN *Node) { - - if old.parent == nil { - setChild(newN, 0, old.children[0]) - setChild(newN, 1, old.children[1]) - - newN.parent = nil - newN.child = -1 - newN.height = old.height - - avl.root = newN - } else { - - setChild(newN, 0, old.children[0]) - setChild(newN, 1, old.children[1]) - - newN.parent = old.parent - newN.child = old.child - newN.height = old.height - old.parent.children[old.child] = newN - } -} - -func setChild(p *Node, child int, node *Node) { - p.children[child] = node - if node != nil { - node.child = child - node.parent = p - } -} - -func setChildNotNil(p *Node, child int, node *Node) { - p.children[child] = node - node.child = child - node.parent = p -} - func (avl *AVL) debugString() string { if avl.size == 0 { return "" @@ -341,111 +312,156 @@ func (avl *AVL) TraversalDepth(leftright int) (result []interface{}) { return } -func (avl *AVL) lrrotate(cur *Node) *Node { +func (avl *AVL) lrrotate(cur *Node) { - r := cur.children[1] - rl := r.children[0] - if cur.parent == nil { - avl.root = rl - rl.parent = nil + const l = 1 + const r = 0 + + movparent := cur.children[l] + mov := movparent.children[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + if mov.children[l] != nil { + movparent.children[r] = mov.children[l] + movparent.children[r].child = 1 } else { - setChildNotNil(cur.parent, cur.child, rl) + movparent.children[r] = nil } - rll := rl.children[0] - rlr := rl.children[1] + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + mov.children[l].child = l + } else { + mov.children[l] = nil + } - setChild(cur, 1, rll) - setChild(r, 0, rlr) + if cur.children[r] != nil { + mov.children[r] = cur.children[r] + mov.children[r].parent = mov + } else { + mov.children[r] = nil + } - setChildNotNil(rl, 0, cur) - setChildNotNil(rl, 1, r) + cur.children[r] = mov + mov.child = r + mov.parent = cur + mov.height = getMaxChildrenHeight(mov) + 1 + movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 - r.height = getMaxChildrenHeight(r) + 1 - rl.height = getMaxChildrenHeight(rl) + 1 - - return rl } -func (avl *AVL) rlrotate(cur *Node) *Node { +func (avl *AVL) rlrotate(cur *Node) { - l := cur.children[0] - lr := l.children[1] - if cur.parent == nil { - avl.root = lr - lr.parent = nil + const l = 0 + const r = 1 + + movparent := cur.children[l] + mov := movparent.children[r] + + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 + + if mov.children[l] != nil { + movparent.children[r] = mov.children[l] + movparent.children[r].child = 1 } else { - setChildNotNil(cur.parent, cur.child, lr) + movparent.children[r] = nil } - lrr := lr.children[1] - lrl := lr.children[0] + if mov.children[r] != nil { + mov.children[l] = mov.children[r] + mov.children[l].child = l + } else { + mov.children[l] = nil + } - setChild(cur, 0, lrr) - setChild(l, 1, lrl) - setChildNotNil(lr, 1, cur) - setChildNotNil(lr, 0, l) + 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.child = r + mov.parent = cur + + mov.height = getMaxChildrenHeight(mov) + 1 + movparent.height = getMaxChildrenHeight(movparent) + 1 cur.height = getMaxChildrenHeight(cur) + 1 - l.height = getMaxChildrenHeight(l) + 1 - lr.height = getMaxChildrenHeight(lr) + 1 - - return lr } -func (avl *AVL) rrotate(cur *Node) *Node { +func (avl *AVL) rrotate(cur *Node) { - l := cur.children[0] + const l = 0 + const r = 1 + // 1 right 0 left + mov := cur.children[l] - setChild(cur, 0, l.children[1]) + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 - l.parent = cur.parent - if cur.parent == nil { - avl.root = l + if mov.children[l] != nil { + mov.children[l].parent, cur.children[l] = cur, mov.children[l] } else { - cur.parent.children[cur.child] = l + cur.children[l] = nil } - l.child = cur.child - setChildNotNil(l, 1, cur) - // l.children[1] = cur - // cur.child = 1 - // cur.parent = l + 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.child = r + + mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 - l.height = getMaxChildrenHeight(l) + 1 - - return l // 返回前 替换为cur节点的节点, 有利余修复高度 } -func (avl *AVL) lrotate(cur *Node) *Node { +func (avl *AVL) lrotate(cur *Node) { - r := cur.children[1] + const l = 1 + const r = 0 + // 1 right 0 left + mov := cur.children[l] - // 右左节点 链接 当前的右节点 - setChild(cur, 1, r.children[0]) + mov.key, mov.value, cur.key, cur.value = cur.key, cur.value, mov.key, mov.value //交换值达到, 相对位移 - // 设置 需要旋转的节点到当前节点的 链条 - r.parent = cur.parent - if cur.parent == nil { - avl.root = r + if mov.children[l] != nil { + mov.children[l].parent, cur.children[l] = cur, mov.children[l] } else { - cur.parent.children[cur.child] = r + cur.children[l] = nil } - r.child = cur.child - // 当前节点旋转到 左边的 链条 - setChildNotNil(r, 0, cur) - // r.children[0] = cur - // cur.child = 0 - // cur.parent = r + 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.child = r + + mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 - r.height = getMaxChildrenHeight(r) + 1 - - return r } func getMaxAndChildrenHeight(cur *Node) (h1, h2, maxh int) { @@ -476,52 +492,52 @@ func getHeight(cur *Node) int { return cur.height } -func (avl *AVL) fixRemoveHeight(cur *Node) { +// func (avl *AVL) fixRemoveHeight(cur *Node) { - for { +// for { - lefth, rigthh, lrmax := getMaxAndChildrenHeight(cur) +// lefth, rigthh, lrmax := getMaxAndChildrenHeight(cur) - // 判断当前节点是否有变化, 如果没变化的时候, 不需要往上修复 - isBreak := false - if cur.height == lrmax+1 { - isBreak = true - } else { - cur.height = lrmax + 1 - } +// // 判断当前节点是否有变化, 如果没变化的时候, 不需要往上修复 +// isBreak := false +// if cur.height == lrmax+1 { +// isBreak = true +// } else { +// cur.height = lrmax + 1 +// } - // 计算高度的差值 绝对值大于2的时候需要旋转 - diff := lefth - rigthh - if diff < -1 { - r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 - if getHeight(r.children[0]) > getHeight(r.children[1]) { - cur = avl.lrrotate(cur) - } else { - cur = avl.lrotate(cur) - } - } else if diff > 1 { - l := cur.children[0] - if getHeight(l.children[1]) > getHeight(l.children[0]) { - cur = avl.rlrotate(cur) - } else { - cur = avl.rrotate(cur) - } - } else { +// // 计算高度的差值 绝对值大于2的时候需要旋转 +// diff := lefth - rigthh +// if diff < -1 { +// r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 +// if getHeight(r.children[0]) > getHeight(r.children[1]) { +// cur = avl.lrrotate(cur) +// } else { +// cur = avl.lrotate(cur) +// } +// } else if diff > 1 { +// l := cur.children[0] +// if getHeight(l.children[1]) > getHeight(l.children[0]) { +// cur = avl.rlrotate(cur) +// } else { +// cur = avl.rrotate(cur) +// } +// } else { - if isBreak { - return - } +// if isBreak { +// return +// } - } +// } - if cur.parent == nil { - return - } +// if cur.parent == nil { +// return +// } - cur = cur.parent - } +// cur = cur.parent +// } -} +// } func (avl *AVL) fixPutHeight(cur *Node) { @@ -535,18 +551,21 @@ func (avl *AVL) fixPutHeight(cur *Node) { if diff < -1 { r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { - cur = avl.lrrotate(cur) + avl.lrrotate(cur) } else { - cur = avl.lrotate(cur) + avl.lrotate(cur) } } else if diff > 1 { + l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { - cur = avl.rlrotate(cur) + avl.rlrotate(cur) } else { - cur = avl.rrotate(cur) + avl.rrotate(cur) + } + } else { // 选择一个child的最大高度 + 1为 高度 if lefth > rigthh { diff --git a/avlkey/avlkey_test.go b/avlkey/avlkey_test.go new file mode 100644 index 0000000..8734277 --- /dev/null +++ b/avlkey/avlkey_test.go @@ -0,0 +1,502 @@ +package avl + +import ( + "testing" + + "github.com/Pallinder/go-randomdata" + "github.com/davecgh/go-spew/spew" + "github.com/emirpasic/gods/trees/avltree" + + "github.com/emirpasic/gods/utils" +) + +// func TestRotate(t *testing.T) { +// avl := New(utils.IntComparator) + +// content := "" +// for i := 0; i < 10; i++ { +// v := randomdata.Number(0, 1000) +// content += spew.Sprint(v) + " " +// avl.Put(v) +// } + +// t.Error(content) +// src := avl.String() +// t.Error(src) + +// lsrc := avl.String() +// t.Error(lsrc) +// // rrotate(&avl.root) +// rsrc := avl.String() +// t.Error(rsrc) + +// if src == rsrc { +// t.Error("src == rsrc") +// } +// } + +// func TestIterator(t *testing.T) { +// avl := New(utils.IntComparator) +// for _, v := range []int{1, 2, 7, 4, 5, 6, 7, 14, 15, 20, 30, 21, 3} { +// // t.Error(v) +// avl.Put(v) + +// } +// t.Error(avl.TraversalDepth(1)) +// t.Error(avl.debugString()) +// iter := avl.Iterator() + +// for iter.Prev() { +// t.Error(iter.Value()) +// } +// t.Error("prev == false", iter.Value(), iter.Prev(), iter.Value()) + +// for iter.Next() { +// t.Error(iter.Value()) +// } +// t.Error("next == false", iter.Value(), iter.Next(), iter.Value()) + +// for iter.Prev() { +// t.Error(iter.Value()) +// } +// t.Error("prev == false", iter.Value()) + +// for i := 0; iter.Next(); i++ { +// t.Error(iter.Value()) +// if i >= 7 { +// break +// } +// } +// t.Error("next == false", iter.Value()) + +// for iter.Prev() { +// t.Error(iter.Value()) +// } +// t.Error("prev == false", iter.Value()) +// } + +// func TestGetAround(t *testing.T) { +// avl := New(utils.IntComparator) +// for _, v := range []int{7, 14, 15, 20, 30, 21, 40, 40, 50, 3, 40, 40, 40} { +// t.Error(v) +// avl.Put(v) +// t.Error(avl.debugString()) +// } +// t.Error(avl.TraversalDepth(1)) +// t.Error(avl.GetAroundNode(40)) +// t.Error(avl.GetAround(40)) +// } + +func TestPutStable(t *testing.T) { + avl := New(utils.IntComparator) + gods := avltree.NewWithIntComparator() + // 44908, 34985, 62991, 4201, 27210, 30707 + for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} { + t.Error(v) + t.Error(avl.debugString()) + avl.Put(v, v) + gods.Put(v, v) + t.Error(avl.debugString()) + t.Error(gods.String()) + } + // avl = New(utils.IntComparator) + // for _, v := range []int{88, 77, 80} { + // avl.Put(v) + // t.Error(avl.String()) + // } +} + +// func TestDiffPutRandom(t *testing.T) { +// avl := New(utils.IntComparator) +// godsavl := avltree.NewWithIntComparator() + +// content := "" +// m := make(map[int]int) +// for i := 0; len(m) < 10; i++ { +// v := randomdata.Number(0, 10000) +// if _, ok := m[v]; !ok { +// m[v] = v +// content += spew.Sprint(v) + " " +// t.Error(v) +// avl.Put(v) +// t.Error(avl.String()) +// godsavl.Put(v, v) +// } +// } +// t.Error(godsavl.String()) +// } + +func TestPutComparatorRandom(t *testing.T) { + + for n := 0; n < 1000000; 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) + "," + // t.Error(v) + avl.Put(v, v) + // t.Error(avl.String()) + godsavl.Put(v, v) + } + } + + if avl.String() != godsavl.String() { + t.Error(godsavl.String()) + t.Error(avl.debugString()) + t.Error(content, n) + break + } + } + + // t.Error(content) + // t.Error(avl.String()) + // t.Error(godsavl.String()) + // t.Error(avl.String() == godsavl.String()) + +} + +// func TestGet(t *testing.T) { +// avl := New(utils.IntComparator) +// for i := 0; i < 15; i++ { +// avl.Put(randomdata.Number(0, 1000)) +// } +// t.Error(avl.String()) +// t.Error(avl.Get(500)) +// } + +// func TestRemoveAll(t *testing.T) { + +// for c := 0; c < 10000; c++ { +// // f, _ := os.OpenFile("./out.log", os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0666) +// // log.SetOutput(f) + +// avl := New(utils.IntComparator) +// var l []int +// for i := 0; i < 100; i++ { +// v := randomdata.Number(0, 100000) +// l = append(l, v) +// avl.Put(v) +// } +// // defer func() { +// // if err := recover(); err != nil { +// // panic(avl.String()) +// // } +// // }() +// // log.Println(avl.TraversalBreadth()) +// for i := 0; i < 100; i++ { +// // log.Println(l[i]) +// // log.Println(avl.debugString()) +// avl.Remove(l[i]) +// } +// } +// } + +// func TestRemove(t *testing.T) { + +// // avl := New(utils.IntComparator) + +// // var l []int +// // for _, v := range []int{86, 97, 9, 61, 37, 45, 97, 43, 95, 8} { +// // l = append(l, v) +// // avl.Put(v) +// // } + +// // for i := 0; i < len(l); i++ { +// // // log.Println(i) +// // log.Println("begin", l[i], avl.debugString()) +// // avl.Remove(l[i]) +// // log.Println("end", l[i], avl.debugString()) +// // } + +// ALL: +// for N := 0; N < 500000; 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 spew.Sprint(gods.Values()) != spew.Sprint(avl.TraversalDepth(-1)) && avl.size != 0 { +// // if gods.String() != avl.String() && gods.Size() != 0 && avl.size != 0 { +// t.Error(src1) +// t.Error(src2) +// t.Error(avl.debugString()) +// t.Error(gods.String()) +// t.Error(l[i]) +// // t.Error(avl.TraversalDepth(-1)) +// // t.Error(gods.Values()) +// break ALL + +// } +// } +// } +// } + +// const CompartorSize = 300000 +// const NumberMax = 60000000 + +// func BenchmarkIterator(b *testing.B) { +// avl := New(utils.IntComparator) +// b.N = CompartorSize + +// for i := 0; i < b.N; i++ { +// v := randomdata.Number(0, NumberMax) +// avl.Put(v) +// } + +// b.ResetTimer() +// b.StartTimer() +// iter := avl.Iterator() +// for iter.Next() { + +// } + +// for iter.Prev() { + +// } + +// for iter.Next() { + +// } + +// } + +// func BenchmarkGodsIterator(b *testing.B) { +// avl := avltree.NewWithIntComparator() +// b.N = CompartorSize + +// for i := 0; i < b.N; i++ { +// v := randomdata.Number(0, NumberMax) +// avl.Put(v, i) +// } + +// b.ResetTimer() +// b.StartTimer() +// iter := avl.Iterator() +// for iter.Next() { + +// } + +// for iter.Prev() { + +// } + +// for iter.Next() { + +// } + +// } + +// func BenchmarkRemove(b *testing.B) { + +// avl := New(utils.IntComparator) +// b.N = CompartorSize + +// var l []int +// for i := 0; i < b.N; i++ { +// v := randomdata.Number(0, NumberMax) +// l = append(l, v) +// avl.Put(v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// for i := 0; i < b.N; i++ { +// avl.Remove(l[i]) +// } +// } + +// func BenchmarkGodsRemove(b *testing.B) { +// avl := avltree.NewWithIntComparator() +// b.N = CompartorSize + +// var l []int +// for i := 0; i < b.N; i++ { +// v := randomdata.Number(0, NumberMax) +// l = append(l, v) +// avl.Put(v, v) +// } + +// b.ResetTimer() +// b.StartTimer() + +// for i := 0; i < b.N; i++ { +// avl.Remove(l[i]) +// } +// } + +// func BenchmarkGoGet(b *testing.B) { +// avl := make(map[int]int) + +// b.N = CompartorSize +// for i := 0; i < b.N; i++ { +// avl[randomdata.Number(0, NumberMax)] = i +// } + +// b.ResetTimer() +// b.StartTimer() +// b.N = CompartorSize + +// var v int +// var ok bool +// for i := 0; i < b.N; i++ { +// v, ok = avl[randomdata.Number(0, NumberMax)] +// } + +// if ok && v == 1 { +// v = 1 +// } +// } + +// func BenchmarkGet(b *testing.B) { + +// avl := New(utils.IntComparator) + +// b.N = CompartorSize +// for i := 0; i < b.N/2; i++ { +// avl.Put(randomdata.Number(0, NumberMax)) +// } + +// b.ResetTimer() +// b.StartTimer() +// for i := 0; i < b.N; i++ { +// avl.Get(randomdata.Number(0, NumberMax)) +// } +// } + +// func BenchmarkGodsRBGet(b *testing.B) { +// rb := redblacktree.NewWithIntComparator() + +// b.N = CompartorSize +// for i := 0; i < b.N/2; i++ { +// rb.Put(randomdata.Number(0, NumberMax), i) +// } + +// b.ResetTimer() +// b.StartTimer() +// for i := 0; i < b.N; i++ { +// rb.Get(randomdata.Number(0, NumberMax)) +// } +// } + +// func BenchmarkGodsAvlGet(b *testing.B) { +// rb := avltree.NewWithIntComparator() + +// b.N = CompartorSize +// for i := 0; i < b.N/2; i++ { +// rb.Put(randomdata.Number(0, NumberMax), i) +// } + +// b.ResetTimer() +// b.StartTimer() +// for i := 0; i < b.N; i++ { +// rb.Get(randomdata.Number(0, NumberMax)) +// } +// } + +// func BenchmarkGoPut(b *testing.B) { +// avl := make(map[int]int) + +// for i := 0; i < 100000; i++ { +// avl[randomdata.Number(0, NumberMax)] = i +// } + +// b.ResetTimer() +// b.StartTimer() +// b.N = CompartorSize + +// for i := 0; i < b.N; i++ { +// avl[randomdata.Number(0, NumberMax)] = i +// } + +// log.Println(avl[12]) +// } + +// func BenchmarkGodsHashmap(b *testing.B) { +// avl := hashmap.New() + +// b.N = CompartorSize * 10 +// for i := 0; i < b.N; i++ { +// avl.Put(randomdata.Number(0, NumberMax), i) +// } + +// // b.ResetTimer() +// // b.StartTimer() +// // b.N = CompartorSize + +// // for i := 0; i < b.N; i++ { +// // avl[randomdata.Number(0, NumberMax)] = i +// // } +// } + +// func BenchmarkPut(b *testing.B) { +// avl := New(utils.IntComparator) + +// for i := 0; i < 100000; i++ { +// avl.Put(randomdata.Number(0, NumberMax)) +// } + +// b.ResetTimer() +// b.StartTimer() +// b.N = CompartorSize +// for i := 0; i < b.N; i++ { +// avl.Put(randomdata.Number(0, NumberMax)) +// } + +// } + +// func BenchmarkGodsRBPut(b *testing.B) { +// rb := redblacktree.NewWithIntComparator() + +// for i := 0; i < 100000; i++ { +// rb.Put(randomdata.Number(0, NumberMax), i) +// } + +// b.ResetTimer() +// b.StartTimer() + +// b.N = CompartorSize +// for i := 0; i < b.N; i++ { +// rb.Put(randomdata.Number(0, NumberMax), i) +// } + +// } + +// func BenchmarkGodsPut(b *testing.B) { +// avl := avltree.NewWithIntComparator() + +// for i := 0; i < 100000; i++ { +// avl.Put(randomdata.Number(0, NumberMax), i) +// } + +// b.ResetTimer() +// b.StartTimer() + +// b.N = CompartorSize +// for i := 0; i < b.N; i++ { +// avl.Put(randomdata.Number(0, NumberMax), i) +// } +// } diff --git a/priority_list/priority_list_test.go b/priority_list/priority_list_test.go index 469533e..c1b89b8 100644 --- a/priority_list/priority_list_test.go +++ b/priority_list/priority_list_test.go @@ -3,6 +3,7 @@ package plist import ( "testing" + "github.com/Pallinder/go-randomdata" "github.com/emirpasic/gods/utils" ) @@ -146,3 +147,23 @@ func TestRemove(t *testing.T) { } } + +func BenchmarkInsert(b *testing.B) { + pl := New(utils.IntComparator) + + b.N = 3000 + + for i := 0; i < b.N; i++ { + v := randomdata.Number(0, 65535) + pl.Push(v) + } + + b.ResetTimer() + b.StartTimer() + for i := 0; i < b.N; i++ { + if i%2 == 0 { + pl.Get(i) + } + } + +}