完善平衡因子
This commit is contained in:
parent
7dcde4cb97
commit
a326f49962
@ -333,14 +333,15 @@ func (avl *Tree) Put(value interface{}) {
|
|||||||
fsize := getSize(fixed)
|
fsize := getSize(fixed)
|
||||||
if fsize == 3 {
|
if fsize == 3 {
|
||||||
lefts, rigths := getChildrenSize(fixed)
|
lefts, rigths := getChildrenSize(fixed)
|
||||||
avl.fixPutHeight(fixed, lefts, rigths)
|
avl.fix3PutHeight(fixed, lefts, rigths)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if cur.size > 9 {
|
if cur.size > 9 {
|
||||||
ls, rs := cur.children[0].size, cur.children[1].size
|
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)
|
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) {
|
func (avl *Tree) lrrotate(cur *Node) {
|
||||||
|
|
||||||
const l = 1
|
const l = 1
|
||||||
@ -547,6 +571,29 @@ func (avl *Tree) lrrotate(cur *Node) {
|
|||||||
// cur.height = getMaxChildrenHeight(cur) + 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) {
|
func (avl *Tree) rlrotate(cur *Node) {
|
||||||
|
|
||||||
const l = 0
|
const l = 0
|
||||||
@ -585,6 +632,25 @@ func (avl *Tree) rlrotate(cur *Node) {
|
|||||||
cur.size = getChildrenSumSize(cur) + 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) {
|
func (avl *Tree) rrotate(cur *Node) {
|
||||||
|
|
||||||
const l = 0
|
const l = 0
|
||||||
@ -628,6 +694,25 @@ func (avl *Tree) rrotate(cur *Node) {
|
|||||||
// cur.height = getMaxChildrenHeight(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) {
|
func (avl *Tree) lrotate(cur *Node) {
|
||||||
|
|
||||||
const l = 1
|
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) {
|
func (avl *Tree) fixPutHeight(cur *Node, lefts, rigths int) {
|
||||||
if lefts > rigths {
|
if lefts > rigths {
|
||||||
l := cur.children[0]
|
l := cur.children[0]
|
||||||
|
@ -8,6 +8,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/huandu/skiplist"
|
||||||
|
|
||||||
"github.com/Pallinder/go-randomdata"
|
"github.com/Pallinder/go-randomdata"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/emirpasic/gods/trees/avltree"
|
"github.com/emirpasic/gods/trees/avltree"
|
||||||
@ -15,7 +17,7 @@ import (
|
|||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CompartorSize = 100000
|
const CompartorSize = 1000000
|
||||||
const NumberMax = 50000000
|
const NumberMax = 50000000
|
||||||
|
|
||||||
func TestSave(t *testing.T) {
|
func TestSave(t *testing.T) {
|
||||||
@ -69,6 +71,7 @@ func TestIterator(t *testing.T) {
|
|||||||
// }
|
// }
|
||||||
// t.Error(avl.Values())
|
// t.Error(avl.Values())
|
||||||
// t.Error(avl.debugString())
|
// t.Error(avl.debugString())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetRange(t *testing.T) {
|
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) {
|
func BenchmarkIterator(b *testing.B) {
|
||||||
tree := New(utils.IntComparator)
|
tree := New(utils.IntComparator)
|
||||||
|
|
||||||
@ -458,7 +525,7 @@ func BenchmarkPut(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
|
|
||||||
execCount := 500
|
execCount := 50
|
||||||
b.N = len(l) * execCount
|
b.N = len(l) * execCount
|
||||||
for i := 0; i < execCount; i++ {
|
for i := 0; i < execCount; i++ {
|
||||||
avl := New(utils.IntComparator)
|
avl := New(utils.IntComparator)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user