diff --git a/avl/avl.go b/avl/avl.go index 0cd381e..8c7db66 100644 --- a/avl/avl.go +++ b/avl/avl.go @@ -1,8 +1,6 @@ package avl import ( - "log" - "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/utils" @@ -12,25 +10,9 @@ type Node struct { children [2]*Node parent *Node height int - size int value interface{} } -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 (n *Node) String() string { if n == nil { return "nil" @@ -233,7 +215,7 @@ func (avl *Tree) GetNode(value interface{}) (*Node, bool) { func (avl *Tree) Put(value interface{}) { avl.size++ - node := &Node{value: value, size: 1} + node := &Node{value: value} if avl.size == 1 { avl.root = node return @@ -254,7 +236,6 @@ func (avl *Tree) Put(value interface{}) { return } - cur.size++ parent = cur c := avl.comparator(value, cur.value) child = (c + 2) / 2 @@ -350,9 +331,9 @@ func (avl *Tree) lrrotate(cur *Node) { cur.children[r] = mov mov.parent = cur - movparent.size = getChildrenSumSize(movparent) + 1 - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 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 @@ -392,9 +373,9 @@ func (avl *Tree) rlrotate(cur *Node) { cur.children[r] = mov mov.parent = cur - movparent.size = getChildrenSumSize(movparent) + 1 - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 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 @@ -469,8 +450,8 @@ func (avl *Tree) rrotate(cur *Node) { // 连接转移后的节点 由于mov只是与cur交换值,parent不变 cur.children[r] = mov - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 @@ -508,8 +489,8 @@ func (avl *Tree) lrotateex(cur *Node) { cur.children[r] = mov - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 @@ -543,8 +524,8 @@ func (avl *Tree) lrotate(cur *Node) { cur.children[r] = mov - mov.size = getChildrenSumSize(mov) + 1 - cur.size = getChildrenSumSize(cur) + 1 + // mov.size = getChildrenSumSize(mov) + 1 + // cur.size = getChildrenSumSize(cur) + 1 mov.height = getMaxChildrenHeight(mov) + 1 cur.height = getMaxChildrenHeight(cur) + 1 @@ -640,25 +621,6 @@ func (avl *Tree) fixPutHeight(cur *Node) { diff := lefth - rigthh if diff < -1 { avl.count++ - switch s := cur.size; s { - default: - ls, rs := getChildrenSize(cur) - if ls > rs { - ls, rs = rs, ls - } - if ls > 7 { - break - } - - hash := ls + rs<<16 - if _, ok := m[hash]; !ok { - m[hash] = 1 - str := "size = " + spew.Sprint(cur.size, "l =", ls, rs) + "\n" - outputfordebug(cur, "", true, &str) - log.Print(str) - } - } - r := cur.children[1] // 根据左旋转的右边节点的子节点 左右高度选择旋转的方式 if getHeight(r.children[0]) > getHeight(r.children[1]) { avl.lrrotate(cur) @@ -667,25 +629,6 @@ func (avl *Tree) fixPutHeight(cur *Node) { } } else if diff > 1 { avl.count++ - switch s := cur.size; s { - default: - ls, rs := getChildrenSize(cur) - if ls > rs { - ls, rs = rs, ls - } - if ls > 7 { - break - } - - hash := ls + rs<<16 - if _, ok := m[hash]; !ok { - m[hash] = 1 - str := "size = " + spew.Sprint(cur.size, "l =", ls, rs) + "\n" - outputfordebug(cur, "", true, &str) - log.Print(str) - } - } - l := cur.children[0] if getHeight(l.children[1]) > getHeight(l.children[0]) { avl.rlrotate(cur) @@ -760,13 +703,13 @@ func outputfordebug(node *Node, prefix string, isTail bool, str *string) { } suffix := "(" - // parentv := "" - // if node.parent == nil { - // parentv = "nil" - // } else { - // parentv = spew.Sprint(node.parent.value) - // } - suffix += spew.Sprint(node.size) + ")" + parentv := "" + if node.parent == nil { + parentv = "nil" + } else { + parentv = spew.Sprint(node.parent.value) + } + suffix += parentv + "|" + spew.Sprint(node.height) + ")" *str += spew.Sprint(node.value) + suffix + "\n" if node.children[0] != nil { diff --git a/avl/avl_test.go b/avl/avl_test.go index 6218a3d..f88523a 100644 --- a/avl/avl_test.go +++ b/avl/avl_test.go @@ -17,7 +17,7 @@ import ( ) const CompartorSize = 1000000 -const NumberMax = 60000000 +const NumberMax = 600 func TestSave(t *testing.T) { @@ -29,13 +29,13 @@ func TestSave(t *testing.T) { //fmt.Println(userBytes) var l []int - m := make(map[int]int) + // 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) - } + // if _, ok := m[v]; !ok { + // m[v] = v + l = append(l, v) + // } } var result bytes.Buffer @@ -138,7 +138,7 @@ func TestPutStable(t *testing.T) { log.SetOutput(f) // 0-1 3 | 2-3 7-8 | 4-7 12-16 | 8-15 20-32 | 16-31 33-58 l := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 19, 20, 21, 22, 30, 41, 41, 41} - for i := 0; i < 100000000; i++ { + for i := 0; i < 100000; i++ { var l []int for len(l) < 1000 { l = append(l, randomdata.Number(0, 100)) @@ -432,18 +432,21 @@ func BenchmarkGodsAvlGet(b *testing.B) { } func BenchmarkPut(b *testing.B) { - avl := New(utils.IntComparator) l := loadTestData() b.ResetTimer() b.StartTimer() - b.N = len(l) - for _, v := range l { - avl.Put(v) + execCount := 50 + b.N = len(l) * execCount + for i := 0; i < execCount; i++ { + avl := New(utils.IntComparator) + for _, v := range l { + avl.Put(v) + } } - b.Log(avl.count) + // b.Log(avl.count) } func BenchmarkGodsRBPut(b *testing.B) { diff --git a/avlindex/avlindex.go b/avlindex/avlindex.go index b86ca3d..dc12665 100644 --- a/avlindex/avlindex.go +++ b/avlindex/avlindex.go @@ -1,8 +1,6 @@ package avlindex import ( - "log" - "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/utils" @@ -166,26 +164,18 @@ func (avl *Tree) Put(value interface{}) { parent.children[child] = node node.parent = parent - fixed := node.parent.parent - - for { - switch fsize := getSize(fixed); fsize { - case 3, 5: - log.Println(fsize) - lefts, rigths := getChildrenSize(fixed) - avl.fixPutHeight(fixed, lefts, rigths) - fixed = fixed.parent - default: - return - } + fixed := parent.parent + fsize := getSize(fixed) + if fsize == 3 { + lefts, rigths := getChildrenSize(fixed) + avl.fixPutHeight(fixed, lefts, rigths) } + return } - if cur.size > 7 { + if cur.size > 9 { ls, rs := cur.children[0].size, cur.children[1].size if rs >= ls*2 || ls >= rs*2 { - // ll, lr := getChildrenSize(cur.children[0]) - // rl, rr := getChildrenSize(cur.children[1]) avl.fixPutHeight(cur, ls, rs) } } @@ -196,7 +186,6 @@ func (avl *Tree) Put(value interface{}) { child = (c + 2) / 2 cur = cur.children[child] } - } func (avl *Tree) debugString() string { @@ -439,22 +428,14 @@ func (avl *Tree) fixRemoveHeight(cur *Node) { } -func abs(n int) int { - y := n >> 31 - return (n ^ y) - y -} +// func abs(n int) int { +// y := n >> 31 +// return (n ^ y) - y +// } func (avl *Tree) fixPutHeight(cur *Node, lefts, rigths int) { avl.count++ - if lefts < rigths { - r := cur.children[1] - rlsize, rrsize := getChildrenSize(r) - if rlsize > rrsize { - avl.lrrotate(cur) - } else { - avl.lrotate(cur) - } - } else { + if lefts > rigths { l := cur.children[0] llsize, lrsize := getChildrenSize(l) if lrsize > llsize { @@ -462,6 +443,14 @@ func (avl *Tree) fixPutHeight(cur *Node, lefts, rigths int) { } else { avl.rrotate(cur) } + } else { + r := cur.children[1] + rlsize, rrsize := getChildrenSize(r) + if rlsize > rrsize { + avl.lrrotate(cur) + } else { + avl.lrotate(cur) + } } } diff --git a/avlindex/avlindex_test.go b/avlindex/avlindex_test.go index 35bab7a..d3f2f4b 100644 --- a/avlindex/avlindex_test.go +++ b/avlindex/avlindex_test.go @@ -14,8 +14,8 @@ import ( "github.com/emirpasic/gods/utils" ) -const CompartorSize = 10000000 -const NumberMax = 500000 +const CompartorSize = 1000 +const NumberMax = 50000000 func TestSave(t *testing.T) { @@ -397,27 +397,28 @@ func BenchmarkGet(b *testing.B) { // } func BenchmarkPut(b *testing.B) { - avl := New(utils.IntComparator) - l := loadTestData() b.ResetTimer() b.StartTimer() - b.N = len(l) - for _, v := range l { - avl.Put(v) + execCount := 50 + b.N = len(l) * execCount + for i := 0; i < execCount; i++ { + avl := New(utils.IntComparator) + for _, v := range l { + avl.Put(v) + } } - b.Log(avl.count) } func TestPutStable(t *testing.T) { - l := []int{14, 18, 20, 21, 22, 23, 19} - // var l []int - // for i := 0; len(l) < 7; i++ { - // l = append(l, randomdata.Number(0, 65)) - // } + // l := []int{14, 18, 20, 21, 22, 23, 19} + var l []int + for i := 0; len(l) < 100; i++ { + l = append(l, randomdata.Number(0, 65)) + } avl := New(utils.IntComparator) for _, v := range l { @@ -425,6 +426,8 @@ func TestPutStable(t *testing.T) { t.Error(avl.debugString(), v) } + t.Error(avl.count) + // t.Error(len(l), avl.debugString(), "\n", "-----------") // 3 6(4) }