完善平衡因子

This commit is contained in:
eson 2019-03-21 04:39:25 +08:00
parent 7dcde4cb97
commit a326f49962
2 changed files with 176 additions and 4 deletions

View File

@ -333,14 +333,15 @@ func (avl *Tree) Put(value interface{}) {
fsize := getSize(fixed)
if fsize == 3 {
lefts, rigths := getChildrenSize(fixed)
avl.fixPutHeight(fixed, lefts, rigths)
avl.fix3PutHeight(fixed, lefts, rigths)
}
return
}
if cur.size > 9 {
ls, rs := cur.children[0].size, cur.children[1].size
if rs >= ls*2 || ls >= rs*2 {
factor := cur.size / 10 // or factor = 1
if rs >= ls*2+factor || ls >= rs*2+factor {
avl.fixPutHeight(cur, ls, rs)
}
}
@ -499,6 +500,29 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in
}
}
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
@ -547,6 +571,29 @@ func (avl *Tree) lrrotate(cur *Node) {
// 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
@ -585,6 +632,25 @@ func (avl *Tree) rlrotate(cur *Node) {
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
@ -628,6 +694,25 @@ func (avl *Tree) rrotate(cur *Node) {
// 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
@ -698,6 +783,26 @@ func (avl *Tree) fixRemoveHeight(cur *Node) {
}
}
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]

View File

@ -8,6 +8,8 @@ import (
"os"
"testing"
"github.com/huandu/skiplist"
"github.com/Pallinder/go-randomdata"
"github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/trees/avltree"
@ -15,7 +17,7 @@ import (
"github.com/emirpasic/gods/utils"
)
const CompartorSize = 100000
const CompartorSize = 1000000
const NumberMax = 50000000
func TestSave(t *testing.T) {
@ -69,6 +71,7 @@ func TestIterator(t *testing.T) {
// }
// t.Error(avl.Values())
// t.Error(avl.debugString())
}
func TestGetRange(t *testing.T) {
@ -305,6 +308,70 @@ 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.GetRange(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)
@ -458,7 +525,7 @@ func BenchmarkPut(b *testing.B) {
b.ResetTimer()
b.StartTimer()
execCount := 500
execCount := 50
b.N = len(l) * execCount
for i := 0; i < execCount; i++ {
avl := New(utils.IntComparator)