完善平衡因子
This commit is contained in:
parent
7dcde4cb97
commit
a326f49962
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user