实现 PriorityQueue Test Benchmark
This commit is contained in:
parent
09dbba1a88
commit
9e2bdb12dd
|
@ -324,13 +324,13 @@ func TestGet(t *testing.T) {
|
|||
func TestRemoveAll(t *testing.T) {
|
||||
|
||||
ALL:
|
||||
for c := 0; c < 5000; c++ {
|
||||
for c := 0; c < 50000; c++ {
|
||||
tree := New(compare.Int)
|
||||
gods := avltree.NewWithIntComparator()
|
||||
var l []int
|
||||
m := make(map[int]int)
|
||||
|
||||
for i := 0; len(l) < 100; i++ {
|
||||
for i := 0; len(l) < 50; i++ {
|
||||
v := randomdata.Number(0, 100000)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
|
@ -340,7 +340,7 @@ ALL:
|
|||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
for i := 0; i < 50; i++ {
|
||||
tree.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
s1 := spew.Sprint(tree.Values())
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
type PriorityQueue struct {
|
||||
queue *vbTree
|
||||
head *tNode
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Iterator() *Iterator {
|
||||
|
@ -22,33 +21,41 @@ func (pq *PriorityQueue) Size() int {
|
|||
}
|
||||
|
||||
func (pq *PriorityQueue) Push(value interface{}) {
|
||||
|
||||
pq.queue.Put(value)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Top() (result interface{}, ok bool) {
|
||||
if pq.head != nil {
|
||||
return pq.head.value, true
|
||||
if pq.queue.top != nil {
|
||||
return pq.queue.top.value, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Pop() (result interface{}, ok bool) {
|
||||
|
||||
if pq.queue.top != nil {
|
||||
result = pq.queue.top.value
|
||||
pq.queue.removeNode(pq.queue.top)
|
||||
return result, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Get(idx int) (interface{}, bool) {
|
||||
return nil, false
|
||||
func (pq *PriorityQueue) Index(idx int) (interface{}, bool) {
|
||||
return pq.queue.Index(idx)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) RemoveWithIndex(idx int) {
|
||||
|
||||
func (pq *PriorityQueue) Get(key interface{}) (interface{}, bool) {
|
||||
return pq.queue.Get(key)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Remove(key interface{}) {
|
||||
func (pq *PriorityQueue) RemoveWithIndex(idx int) bool {
|
||||
return pq.queue.RemoveIndex(idx)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Remove(key interface{}) bool {
|
||||
return pq.queue.Remove(key)
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue) Values() []interface{} {
|
||||
return nil
|
||||
return pq.queue.Values()
|
||||
}
|
||||
|
|
|
@ -3,35 +3,178 @@ package pqueue
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Pallinder/go-randomdata"
|
||||
|
||||
"474420502.top/eson/structure/compare"
|
||||
)
|
||||
|
||||
func TestPush(t *testing.T) {
|
||||
func TestQueuePush(t *testing.T) {
|
||||
pq := New(compare.Int)
|
||||
for i := 0; i < 10; i++ {
|
||||
v := randomdata.Number(0, 100)
|
||||
for _, v := range []int{32, 10, 53, 78, 90, 1, 4} {
|
||||
pq.Push(v)
|
||||
if v, ok := pq.Top(); ok {
|
||||
} else {
|
||||
t.Error(v)
|
||||
}
|
||||
t.Error(pq.Pop())
|
||||
t.Error(pq.Pop())
|
||||
t.Error(pq.Pop())
|
||||
t.Error(pq.Pop())
|
||||
t.Error(pq.Pop())
|
||||
}
|
||||
|
||||
func TestPop(t *testing.T) {
|
||||
pq := New(compare.Int)
|
||||
for i := 0; i < 10; i++ {
|
||||
v := randomdata.Number(0, 100)
|
||||
pq.Push(v)
|
||||
if v, ok := pq.Top(); ok {
|
||||
if v != 90 {
|
||||
t.Error(v)
|
||||
}
|
||||
} else {
|
||||
t.Error(v)
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
t.Error(pq.Pop())
|
||||
}
|
||||
|
||||
func TestQueuePop(t *testing.T) {
|
||||
pq := New(compare.Int)
|
||||
for _, v := range []int{32, 10, 53, 78, 90, 1, 4} {
|
||||
pq.Push(v)
|
||||
if v, ok := pq.Top(); ok {
|
||||
} else {
|
||||
t.Error(v)
|
||||
}
|
||||
}
|
||||
|
||||
l := []int{90, 78, 53, 32, 10, 4, 1}
|
||||
for _, lv := range l {
|
||||
if v, ok := pq.Pop(); ok {
|
||||
if v != lv {
|
||||
t.Error(v)
|
||||
}
|
||||
} else {
|
||||
t.Error(v)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := pq.Pop(); ok {
|
||||
t.Error(v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueueGet(t *testing.T) {
|
||||
pq := New(compare.Int)
|
||||
l := []int{32, 10, 53, 78, 90, 1, 4}
|
||||
for _, v := range l {
|
||||
pq.Push(v)
|
||||
}
|
||||
|
||||
if v, ok := pq.Get(0); ok {
|
||||
t.Error(v)
|
||||
}
|
||||
|
||||
if v, ok := pq.Get(70); ok {
|
||||
t.Error(v)
|
||||
}
|
||||
|
||||
for _, v := range l {
|
||||
if gv, ok := pq.Get(v); ok {
|
||||
if gv != v {
|
||||
t.Error("Get value is error, value is", gv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestQueueIndex(t *testing.T) {
|
||||
pq := New(compare.Int)
|
||||
for _, v := range []int{32, 10, 53, 78, 90, 1, 4} {
|
||||
pq.Push(v)
|
||||
}
|
||||
|
||||
l := []int{90, 78, 53, 32, 10, 4, 1}
|
||||
for i, lv := range l {
|
||||
|
||||
if v, ok := pq.Index(len(l) - i - 1); ok {
|
||||
if v != l[len(l)-i-1] {
|
||||
t.Error(v)
|
||||
}
|
||||
} else {
|
||||
t.Error(i, "index is not exist")
|
||||
}
|
||||
|
||||
if v, ok := pq.Index(i); ok {
|
||||
if v != lv {
|
||||
t.Error(v)
|
||||
}
|
||||
} else {
|
||||
t.Error(i, "index is not exist")
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := pq.Index(-1); ok {
|
||||
if v != 1 {
|
||||
t.Error(v)
|
||||
}
|
||||
} else {
|
||||
t.Error("-1 index is not exist")
|
||||
}
|
||||
|
||||
if v, ok := pq.Index(pq.Size()); ok {
|
||||
t.Error("index is exits", pq.Size(), v)
|
||||
}
|
||||
|
||||
if v, ok := pq.Index(pq.Size() - 1); !ok {
|
||||
if v != 1 {
|
||||
t.Error("the last value is 1 not is ", v)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := pq.Index(-10); ok {
|
||||
t.Error("-10 index is exits", v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkQueueGet(b *testing.B) {
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
pq := New(compare.Int)
|
||||
for _, v := range l {
|
||||
pq.Push(v)
|
||||
}
|
||||
|
||||
execCount := 5
|
||||
b.N = len(l) * execCount
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
ALL:
|
||||
for i := 0; i < execCount; i++ {
|
||||
for _, v := range l {
|
||||
if gv, ok := pq.Get(v); !ok {
|
||||
b.Error(gv)
|
||||
break ALL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkQueueIndex(b *testing.B) {
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
pq := New(compare.Int)
|
||||
for _, v := range l {
|
||||
pq.Push(v)
|
||||
}
|
||||
|
||||
execCount := 2
|
||||
b.N = len(l) * execCount
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
ALL:
|
||||
for i := 0; i < execCount; i++ {
|
||||
for idx := range l {
|
||||
if v, ok := pq.Index(idx); !ok {
|
||||
b.Error(v)
|
||||
break ALL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +204,7 @@ func BenchmarkPriorityPop(b *testing.B) {
|
|||
pq.Push(v)
|
||||
}
|
||||
|
||||
b.N = len(l) / 1000
|
||||
b.N = len(l)
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
|
|
|
@ -60,19 +60,6 @@ func (tree *vbTree) Size() int {
|
|||
func (tree *vbTree) indexNode(idx int) *tNode {
|
||||
cur := tree.root
|
||||
if idx >= 0 {
|
||||
for cur != nil {
|
||||
ls := getSize(cur.children[0])
|
||||
if idx == ls {
|
||||
return cur
|
||||
} else if idx < ls {
|
||||
cur = cur.children[0]
|
||||
} else {
|
||||
idx = idx - ls - 1
|
||||
cur = cur.children[1]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
idx = -idx - 1
|
||||
for cur != nil {
|
||||
rs := getSize(cur.children[1])
|
||||
if idx == rs {
|
||||
|
@ -84,6 +71,19 @@ func (tree *vbTree) indexNode(idx int) *tNode {
|
|||
cur = cur.children[0]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
idx = -idx - 1
|
||||
for cur != nil {
|
||||
ls := getSize(cur.children[0])
|
||||
if idx == ls {
|
||||
return cur
|
||||
} else if idx < ls {
|
||||
cur = cur.children[0]
|
||||
} else {
|
||||
idx = idx - ls - 1
|
||||
cur = cur.children[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -166,10 +166,15 @@ func (tree *vbTree) RemoveIndex(idx int) bool {
|
|||
func (tree *vbTree) removeNode(n *tNode) {
|
||||
if tree.root.size == 1 {
|
||||
tree.root = nil
|
||||
tree.top = nil
|
||||
// return n
|
||||
return
|
||||
}
|
||||
|
||||
if tree.top == n {
|
||||
tree.top = tree.iter.GetPrev(n, 1)
|
||||
}
|
||||
|
||||
ls, rs := getChildrenSize(n)
|
||||
if ls == 0 && rs == 0 {
|
||||
p := n.parent
|
||||
|
@ -208,11 +213,12 @@ func (tree *vbTree) removeNode(n *tNode) {
|
|||
|
||||
cparent := cur.parent
|
||||
// 修改为interface 交换
|
||||
n.value, cur.value = cur.value, n.value
|
||||
// n.value, cur.value = cur.value, n.value
|
||||
tree.replace(n, cur)
|
||||
|
||||
// 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度
|
||||
if cparent == n {
|
||||
tree.fixSizeWithRemove(n)
|
||||
tree.fixSizeWithRemove(cur)
|
||||
} else {
|
||||
tree.fixSizeWithRemove(cparent)
|
||||
}
|
||||
|
@ -431,15 +437,21 @@ func (tree *vbTree) Put(key interface{}) {
|
|||
tNode := &tNode{value: key, size: 1}
|
||||
if tree.root == nil {
|
||||
tree.root = tNode
|
||||
tree.top = tNode
|
||||
return
|
||||
}
|
||||
|
||||
if tree.Compare(key, tree.top.value) > 0 {
|
||||
tree.top = tNode
|
||||
}
|
||||
|
||||
for cur := tree.root; ; {
|
||||
|
||||
if cur.size > 8 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if cur.children[1].size >= cur.children[0].size*2+factor || cur.children[0].size >= cur.children[1].size*2+factor {
|
||||
cur = tree.fixSize(cur)
|
||||
ls, rs := cur.children[0].size, cur.children[1].size
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
cur = tree.fixSize(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,6 +469,7 @@ func (tree *vbTree) Put(key interface{}) {
|
|||
tree.rrotate3(cur.parent)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
cur = cur.children[0]
|
||||
|
@ -636,6 +649,24 @@ func setChild(cur *tNode, cidx int, child *tNode) {
|
|||
}
|
||||
}
|
||||
|
||||
func (tree *vbTree) replace(old, new *tNode) {
|
||||
|
||||
setChild(new, 0, old.children[0])
|
||||
setChild(new, 1, old.children[1])
|
||||
|
||||
if old.parent == nil {
|
||||
tree.root = new
|
||||
} else {
|
||||
if old.parent.children[1] == old {
|
||||
old.parent.children[1] = new
|
||||
} else {
|
||||
old.parent.children[0] = new
|
||||
}
|
||||
}
|
||||
new.size = old.size
|
||||
new.parent = old.parent
|
||||
}
|
||||
|
||||
func (tree *vbTree) takeParent(token, person *tNode) {
|
||||
if token.parent == nil {
|
||||
tree.root = person
|
||||
|
@ -739,55 +770,6 @@ func (tree *vbTree) rlrotate(cur *tNode) *tNode {
|
|||
lrn.size = getChildrenSumSize(lrn) + 1
|
||||
|
||||
return lrn
|
||||
|
||||
// movparent := cur.children[l]
|
||||
// mov := movparent.children[r]
|
||||
|
||||
// mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
||||
|
||||
// if mov.children[l] != nil {
|
||||
// movparent.children[r] = mov.children[l]
|
||||
// movparent.children[r].parent = movparent
|
||||
// } else {
|
||||
// movparent.children[r] = nil
|
||||
// }
|
||||
|
||||
// if mov.children[r] != nil {
|
||||
// mov.children[l] = mov.children[r]
|
||||
// } 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.parent = cur
|
||||
|
||||
// movparent.size = getChildrenSumSize(movparent) + 1
|
||||
// mov.size = getChildrenSumSize(mov) + 1
|
||||
// cur.size = getChildrenSumSize(cur) + 1
|
||||
}
|
||||
|
||||
func (tree *vbTree) replace(old, new *tNode) {
|
||||
|
||||
new.children[0] = old.children[0]
|
||||
new.children[1] = old.children[1]
|
||||
|
||||
if old.parent == nil {
|
||||
tree.root = new
|
||||
} else {
|
||||
if old.parent.children[1] == old {
|
||||
old.parent.children[1] = new
|
||||
} else {
|
||||
old.parent.children[0] = new
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (tree *vbTree) rrotate3(cur *tNode) *tNode {
|
||||
|
@ -877,16 +859,17 @@ func (tree *vbTree) fixSizeWithRemove(cur *tNode) {
|
|||
cur.size--
|
||||
if cur.size > 8 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if cur.children[1].size >= cur.children[0].size*2+factor || cur.children[0].size >= cur.children[1].size*2+factor {
|
||||
cur = tree.fixSize(cur)
|
||||
ls, rs := getChildrenSize(cur)
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
cur = tree.fixSize(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
cur = cur.parent
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *vbTree) fixSize(cur *tNode) *tNode {
|
||||
if cur.children[0].size > cur.children[1].size {
|
||||
func (tree *vbTree) fixSize(cur *tNode, ls, rs int) *tNode {
|
||||
if ls > rs {
|
||||
llsize, lrsize := getChildrenSize(cur.children[0])
|
||||
if lrsize > llsize {
|
||||
return tree.rlrotate(cur)
|
||||
|
|
|
@ -194,15 +194,26 @@ func TestPutStable(t *testing.T) {
|
|||
for i := 0; i < 40; i++ {
|
||||
v := randomdata.Number(0, 100)
|
||||
tree.Put(v)
|
||||
|
||||
t.Error(tree.top, v)
|
||||
// t.Error(i, v)
|
||||
// t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
for i := 0; i < 40; i++ {
|
||||
v, _ := tree.Index(0)
|
||||
tree.RemoveIndex(0)
|
||||
t.Error(i, v)
|
||||
t.Error(tree.debugString())
|
||||
if tree.top != nil {
|
||||
t.Error(tree.top)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPutComparatorRandom(t *testing.T) {
|
||||
|
||||
for n := 0; n < 50000; n++ {
|
||||
for n := 0; n < 30000; n++ {
|
||||
tree := newVBT(compare.Int)
|
||||
godsavl := avltree.NewWithIntComparator()
|
||||
|
||||
|
@ -330,7 +341,7 @@ func TestTravalsal(t *testing.T) {
|
|||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
ALL:
|
||||
for c := 0; c < 10000; c++ {
|
||||
for c := 0; c < 20000; c++ {
|
||||
tree := newVBT(compare.Int)
|
||||
gods := avltree.NewWithIntComparator()
|
||||
var l []int
|
||||
|
@ -353,12 +364,10 @@ ALL:
|
|||
s1 := spew.Sprint(tree.Values())
|
||||
s2 := spew.Sprint(gods.Values())
|
||||
if s1 != s2 {
|
||||
// t.Error("avl remove error", "avlsize = ", tree.Size())
|
||||
// t.Error(beforce)
|
||||
// t.Error(after)
|
||||
// t.Error(tree.root, i, l[i])
|
||||
// t.Error(s1)
|
||||
// t.Error(s2)
|
||||
t.Error("avl remove error", "avlsize = ", tree.Size())
|
||||
t.Error(tree.root, i, l[i])
|
||||
t.Error(s1)
|
||||
t.Error(s2)
|
||||
break ALL
|
||||
}
|
||||
}
|
||||
|
|
14
vbt/vbt.go
14
vbt/vbt.go
|
@ -436,8 +436,9 @@ func (tree *Tree) Put(key interface{}) {
|
|||
|
||||
if cur.size > 8 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if cur.children[1].size >= cur.children[0].size*2+factor || cur.children[0].size >= cur.children[1].size*2+factor {
|
||||
tree.fixSize(cur)
|
||||
ls, rs := cur.children[0].size, cur.children[1].size
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
tree.fixSize(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -866,16 +867,17 @@ func (tree *Tree) fixSizeWithRemove(cur *Node) {
|
|||
cur.size--
|
||||
if cur.size > 8 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if cur.children[1].size >= cur.children[0].size*2+factor || cur.children[0].size >= cur.children[1].size*2+factor {
|
||||
tree.fixSize(cur)
|
||||
ls, rs := getChildrenSize(cur)
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
tree.fixSize(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
cur = cur.parent
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Tree) fixSize(cur *Node) {
|
||||
if cur.children[0].size > cur.children[1].size {
|
||||
func (tree *Tree) fixSize(cur *Node, ls, rs int) {
|
||||
if ls > rs {
|
||||
llsize, lrsize := getChildrenSize(cur.children[0])
|
||||
if lrsize > llsize {
|
||||
tree.rlrotate(cur)
|
||||
|
|
|
@ -319,13 +319,13 @@ func TestTravalsal(t *testing.T) {
|
|||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
ALL:
|
||||
for c := 0; c < 5000; c++ {
|
||||
for c := 0; c < 10000; c++ {
|
||||
tree := New(compare.Int)
|
||||
gods := avltree.NewWithIntComparator()
|
||||
var l []int
|
||||
m := make(map[int]int)
|
||||
|
||||
for i := 0; len(l) < 20; i++ {
|
||||
for i := 0; len(l) < 100; i++ {
|
||||
v := randomdata.Number(0, 100000)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
|
@ -335,7 +335,7 @@ ALL:
|
|||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
for i := 0; i < 100; i++ {
|
||||
|
||||
tree.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
|
@ -391,6 +391,23 @@ ALL:
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkSkipRemove(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()
|
||||
|
||||
for _, v := range l {
|
||||
sl.Remove(v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSkipListGet(b *testing.B) {
|
||||
sl := skiplist.New(skiplist.Int)
|
||||
l := loadTestData()
|
||||
|
|
|
@ -433,8 +433,9 @@ func (tree *Tree) Put(key, value interface{}) {
|
|||
|
||||
if cur.size > 8 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if cur.children[1].size >= cur.children[0].size*2+factor || cur.children[0].size >= cur.children[1].size*2+factor {
|
||||
tree.fixSize(cur)
|
||||
ls, rs := cur.children[0].size, cur.children[1].size
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
tree.fixSize(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -870,56 +871,17 @@ func (tree *Tree) fixSizeWithRemove(cur *Node) {
|
|||
cur.size--
|
||||
if cur.size > 8 {
|
||||
factor := cur.size / 10 // or factor = 1
|
||||
if cur.children[1].size >= cur.children[0].size*2+factor || cur.children[0].size >= cur.children[1].size*2+factor {
|
||||
tree.fixSize(cur)
|
||||
ls, rs := getChildrenSize(cur)
|
||||
if rs >= ls*2+factor || ls >= rs*2+factor {
|
||||
tree.fixSize(cur, ls, rs)
|
||||
}
|
||||
}
|
||||
cur = cur.parent
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Tree) fix3Size(cur *Node, lefts, rigths int) {
|
||||
if lefts > rigths {
|
||||
l := cur.children[0]
|
||||
llsize, lrsize := getChildrenSize(l)
|
||||
if lrsize > llsize {
|
||||
tree.rlrotate3(cur)
|
||||
} else {
|
||||
tree.rrotate3(cur)
|
||||
}
|
||||
} else {
|
||||
r := cur.children[1]
|
||||
rlsize, rrsize := getChildrenSize(r)
|
||||
if rlsize > rrsize {
|
||||
tree.lrrotate3(cur)
|
||||
} else {
|
||||
tree.lrotate3(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Tree) fix6Size(cur *Node, lefts, rigths int) {
|
||||
if lefts > rigths {
|
||||
l := cur.children[0]
|
||||
llsize, lrsize := getChildrenSize(l)
|
||||
if lrsize > llsize {
|
||||
tree.rlrotate(cur)
|
||||
} else {
|
||||
tree.rrotate(cur)
|
||||
}
|
||||
} else {
|
||||
r := cur.children[1]
|
||||
rlsize, rrsize := getChildrenSize(r)
|
||||
if rlsize > rrsize {
|
||||
tree.lrrotate(cur)
|
||||
} else {
|
||||
tree.lrotate(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Tree) fixSize(cur *Node) {
|
||||
if cur.children[0].size > cur.children[1].size {
|
||||
func (tree *Tree) fixSize(cur *Node, ls, rs int) {
|
||||
if ls > rs {
|
||||
llsize, lrsize := getChildrenSize(cur.children[0])
|
||||
if lrsize > llsize {
|
||||
tree.rlrotate(cur)
|
||||
|
|
|
@ -325,7 +325,7 @@ ALL:
|
|||
var l []int
|
||||
m := make(map[int]int)
|
||||
|
||||
for i := 0; len(l) < 20; i++ {
|
||||
for i := 0; len(l) < 50; i++ {
|
||||
v := randomdata.Number(0, 100000)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
|
@ -335,7 +335,7 @@ ALL:
|
|||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
for i := 0; i < 50; i++ {
|
||||
|
||||
tree.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
|
|
Loading…
Reference in New Issue
Block a user