priority_queue TODO
This commit is contained in:
parent
dd4c76f144
commit
6f6a64ed08
|
@ -247,17 +247,11 @@ 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 < 100000; i++ {
|
||||
// var l []int
|
||||
// for len(l) < 1000 {
|
||||
// l = append(l, randomdata.Number(0, 100))
|
||||
// }
|
||||
|
||||
// tree := New(compare.Int)
|
||||
// for _, v := range l {
|
||||
// tree.Put(v)
|
||||
// }
|
||||
// }
|
||||
tree := New(compare.Int)
|
||||
for i := 0; i < 10; i++ {
|
||||
tree.Put(randomdata.Number(0, 100))
|
||||
}
|
||||
t.Error(tree.debugString())
|
||||
|
||||
// t.Error(tree.debugString(), tree.TraversalBreadth(), "\n", "-----------")
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package pqueue
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"474420502.top/eson/structure/compare"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
@ -203,17 +205,11 @@ func (tree *vbTree) removeNode(n *tNode) {
|
|||
}
|
||||
|
||||
cparent := cur.parent
|
||||
replaceNodeMayRoot(n, cur)
|
||||
// 修改为interface 交换
|
||||
n.value, cur.value = cur.value, n.value
|
||||
// n.value, cur.value = cur.value, n.value
|
||||
|
||||
// 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度
|
||||
if cparent == n {
|
||||
tree.fixSizeWithRemove(n)
|
||||
} else {
|
||||
tree.fixSizeWithRemove(cparent)
|
||||
}
|
||||
|
||||
// return cur
|
||||
tree.fixSizeWithRemove(cparent)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -624,44 +620,42 @@ func (tree *vbTree) lrrotate3(cur *tNode) {
|
|||
cur.children[l].size = 1
|
||||
}
|
||||
|
||||
func (tree *vbTree) lrrotate(cur *tNode) {
|
||||
func (tree *vbTree) lrrotate(cur *tNode) *tNode {
|
||||
|
||||
const l = 1
|
||||
const r = 0
|
||||
|
||||
movparent := cur.children[l]
|
||||
mov := movparent.children[r]
|
||||
// 1 right 0 left
|
||||
ln := cur.children[l]
|
||||
lrn := ln.children[r] // 待转换的节点
|
||||
lrln := lrn.children[l]
|
||||
lrrn := lrn.children[r]
|
||||
|
||||
mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
||||
ln.children[r] = lrln
|
||||
ln.children[r].parent = ln
|
||||
|
||||
if mov.children[l] != nil {
|
||||
movparent.children[r] = mov.children[l]
|
||||
movparent.children[r].parent = movparent
|
||||
//movparent.children[r].child = l
|
||||
} else {
|
||||
movparent.children[r] = nil
|
||||
if cur.parent != nil {
|
||||
if cur.parent.children[l] == cur {
|
||||
cur.parent.children[l] = lrn
|
||||
} else {
|
||||
cur.parent.children[r] = lrn
|
||||
}
|
||||
}
|
||||
|
||||
if mov.children[r] != nil {
|
||||
mov.children[l] = mov.children[r]
|
||||
//mov.children[l].child = l
|
||||
} else {
|
||||
mov.children[l] = nil
|
||||
}
|
||||
lrn.children[l] = cur.children[l]
|
||||
lrn.children[l].parent = lrn
|
||||
|
||||
if cur.children[r] != nil {
|
||||
mov.children[r] = cur.children[r]
|
||||
mov.children[r].parent = mov
|
||||
} else {
|
||||
mov.children[r] = nil
|
||||
}
|
||||
lrn.children[l] = cur
|
||||
lrn.children[l].parent = lrn
|
||||
|
||||
cur.children[r] = mov
|
||||
mov.parent = cur
|
||||
cur.children[l] = lrrn
|
||||
cur.children[l].parent = cur
|
||||
|
||||
movparent.size = getChildrenSumSize(movparent) + 1
|
||||
mov.size = getChildrenSumSize(mov) + 1
|
||||
ln.size = getChildrenSumSize(ln) + 1
|
||||
cur.size = getChildrenSumSize(cur) + 1
|
||||
lrn.size = getChildrenSumSize(lrn) + 1
|
||||
|
||||
return lrn
|
||||
}
|
||||
|
||||
func (tree *vbTree) rlrotate3(cur *tNode) {
|
||||
|
@ -687,42 +681,42 @@ func (tree *vbTree) rlrotate3(cur *tNode) {
|
|||
cur.children[l].size = 1
|
||||
}
|
||||
|
||||
func (tree *vbTree) rlrotate(cur *tNode) {
|
||||
func (tree *vbTree) rlrotate(cur *tNode) *tNode {
|
||||
|
||||
const l = 0
|
||||
const r = 1
|
||||
|
||||
movparent := cur.children[l]
|
||||
mov := movparent.children[r]
|
||||
// 1 right 0 left
|
||||
ln := cur.children[l]
|
||||
lrn := ln.children[r] // 待转换的节点
|
||||
lrln := lrn.children[l]
|
||||
lrrn := lrn.children[r]
|
||||
|
||||
mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
||||
ln.children[r] = lrln
|
||||
ln.children[r].parent = ln
|
||||
|
||||
if mov.children[l] != nil {
|
||||
movparent.children[r] = mov.children[l]
|
||||
movparent.children[r].parent = movparent
|
||||
} else {
|
||||
movparent.children[r] = nil
|
||||
if cur.parent != nil {
|
||||
if cur.parent.children[l] == cur {
|
||||
cur.parent.children[l] = lrn
|
||||
} else {
|
||||
cur.parent.children[r] = lrn
|
||||
}
|
||||
}
|
||||
|
||||
if mov.children[r] != nil {
|
||||
mov.children[l] = mov.children[r]
|
||||
} else {
|
||||
mov.children[l] = nil
|
||||
}
|
||||
lrn.children[l] = cur.children[l]
|
||||
lrn.children[l].parent = lrn
|
||||
|
||||
if cur.children[r] != nil {
|
||||
mov.children[r] = cur.children[r]
|
||||
mov.children[r].parent = mov
|
||||
} else {
|
||||
mov.children[r] = nil
|
||||
}
|
||||
lrn.children[l] = cur
|
||||
lrn.children[l].parent = lrn
|
||||
|
||||
cur.children[r] = mov
|
||||
mov.parent = cur
|
||||
cur.children[l] = lrrn
|
||||
cur.children[l].parent = cur
|
||||
|
||||
movparent.size = getChildrenSumSize(movparent) + 1
|
||||
mov.size = getChildrenSumSize(mov) + 1
|
||||
ln.size = getChildrenSumSize(ln) + 1
|
||||
cur.size = getChildrenSumSize(cur) + 1
|
||||
lrn.size = getChildrenSumSize(lrn) + 1
|
||||
|
||||
return lrn
|
||||
}
|
||||
|
||||
func (tree *vbTree) rrotate3(cur *tNode) {
|
||||
|
@ -744,38 +738,35 @@ func (tree *vbTree) rrotate3(cur *tNode) {
|
|||
mov.size = 1
|
||||
}
|
||||
|
||||
func (tree *vbTree) rrotate(cur *tNode) {
|
||||
func (tree *vbTree) rrotate(cur *tNode) *tNode {
|
||||
|
||||
const l = 0
|
||||
const r = 1
|
||||
// 1 right 0 left
|
||||
mov := cur.children[l]
|
||||
ln := cur.children[l]
|
||||
lrn := ln.children[r] // 待移到另一则的节点
|
||||
|
||||
mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
||||
if cur.parent != nil {
|
||||
if cur.parent.children[l] == cur {
|
||||
cur.parent.children[l] = ln
|
||||
} else {
|
||||
cur.parent.children[r] = ln
|
||||
}
|
||||
}
|
||||
ln.parent = cur.parent
|
||||
|
||||
// mov.children[l]不可能为nil
|
||||
mov.children[l].parent = cur
|
||||
cur.children[l] = mov.children[l]
|
||||
ln.children[r] = cur
|
||||
ln.children[r].parent = ln
|
||||
|
||||
// 解决mov节点孩子转移的问题
|
||||
if mov.children[r] != nil {
|
||||
mov.children[l] = mov.children[r]
|
||||
} else {
|
||||
mov.children[l] = nil
|
||||
cur.children[l] = lrn
|
||||
if lrn != nil {
|
||||
cur.children[l].parent = cur
|
||||
}
|
||||
|
||||
if cur.children[r] != nil {
|
||||
mov.children[r] = cur.children[r]
|
||||
mov.children[r].parent = mov
|
||||
} else {
|
||||
mov.children[r] = nil
|
||||
}
|
||||
|
||||
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
|
||||
cur.children[r] = mov
|
||||
|
||||
mov.size = getChildrenSumSize(mov) + 1
|
||||
cur.size = getChildrenSumSize(cur) + 1
|
||||
ln.size = getChildrenSumSize(ln) + 1
|
||||
|
||||
return ln
|
||||
}
|
||||
|
||||
func (tree *vbTree) lrotate3(cur *tNode) {
|
||||
|
@ -797,38 +788,35 @@ func (tree *vbTree) lrotate3(cur *tNode) {
|
|||
mov.size = 1
|
||||
}
|
||||
|
||||
func (tree *vbTree) lrotate(cur *tNode) {
|
||||
func (tree *vbTree) lrotate(cur *tNode) *tNode {
|
||||
|
||||
const l = 1
|
||||
const r = 0
|
||||
// 1 right 0 left
|
||||
mov := cur.children[l]
|
||||
|
||||
mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
||||
ln := cur.children[l]
|
||||
lrn := ln.children[r] // 待移到另一则的节点
|
||||
|
||||
// mov.children[l]不可能为nil
|
||||
mov.children[l].parent = cur
|
||||
cur.children[l] = mov.children[l]
|
||||
if cur.parent != nil {
|
||||
if cur.parent.children[l] == cur {
|
||||
cur.parent.children[l] = ln
|
||||
} else {
|
||||
cur.parent.children[r] = ln
|
||||
}
|
||||
}
|
||||
ln.parent = cur.parent
|
||||
|
||||
// 解决mov节点孩子转移的问题
|
||||
if mov.children[r] != nil {
|
||||
mov.children[l] = mov.children[r]
|
||||
} else {
|
||||
mov.children[l] = nil
|
||||
ln.children[r] = cur
|
||||
ln.children[r].parent = ln
|
||||
|
||||
cur.children[l] = lrn
|
||||
if lrn != nil {
|
||||
cur.children[l].parent = cur
|
||||
}
|
||||
|
||||
if cur.children[r] != nil {
|
||||
mov.children[r] = cur.children[r]
|
||||
mov.children[r].parent = mov
|
||||
} else {
|
||||
mov.children[r] = nil
|
||||
}
|
||||
|
||||
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
|
||||
cur.children[r] = mov
|
||||
|
||||
mov.size = getChildrenSumSize(mov) + 1
|
||||
cur.size = getChildrenSumSize(cur) + 1
|
||||
ln.size = getChildrenSumSize(ln) + 1
|
||||
|
||||
return ln
|
||||
}
|
||||
|
||||
func getChildrenSumSize(cur *tNode) int {
|
||||
|
@ -880,22 +868,87 @@ func (tree *vbTree) fix3Size(cur *tNode, lefts, rigths int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (tree *vbTree) fixSize(cur *tNode, lefts, rigths int) {
|
||||
func (tree *vbTree) fixSize(cur *tNode, lefts, rigths int) *tNode {
|
||||
if lefts > rigths {
|
||||
l := cur.children[0]
|
||||
llsize, lrsize := getChildrenSize(l)
|
||||
if lrsize > llsize {
|
||||
tree.rlrotate(cur)
|
||||
log.Println("rlrotate")
|
||||
return tree.rlrotate(cur)
|
||||
} else {
|
||||
tree.rrotate(cur)
|
||||
log.Println("rrotate")
|
||||
return tree.rrotate(cur)
|
||||
}
|
||||
} else {
|
||||
r := cur.children[1]
|
||||
rlsize, rrsize := getChildrenSize(r)
|
||||
if rlsize > rrsize {
|
||||
tree.lrrotate(cur)
|
||||
log.Println("lrrotate")
|
||||
return tree.lrrotate(cur)
|
||||
} else {
|
||||
tree.lrotate(cur)
|
||||
log.Println("lrotate")
|
||||
return tree.lrotate(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func insertNode(parent *tNode, childidx int, newn *tNode) {
|
||||
child := parent.children[childidx]
|
||||
parent.children[childidx] = newn
|
||||
newn.parent = parent
|
||||
// 如果是旋转 还需要把 newn.children[childidx] 转到children的紧邻
|
||||
newn.children[childidx] = child
|
||||
}
|
||||
|
||||
func replaceNodeNotRoot(oldn, newn *tNode) {
|
||||
if newn.parent == oldn {
|
||||
if oldn.children[0] == newn {
|
||||
oldn.children[0] = nil
|
||||
} else {
|
||||
oldn.children[1] = nil
|
||||
}
|
||||
}
|
||||
|
||||
newn.children[0] = oldn.children[0]
|
||||
newn.children[1] = oldn.children[1]
|
||||
newn.parent = oldn.parent
|
||||
|
||||
if oldn.parent.children[0] == oldn {
|
||||
oldn.parent.children[0] = newn
|
||||
} else {
|
||||
oldn.parent.children[1] = newn
|
||||
}
|
||||
}
|
||||
|
||||
func replaceNodeMayRoot(oldn, newn *tNode) {
|
||||
if newn.parent == oldn {
|
||||
if oldn.children[0] == newn {
|
||||
oldn.children[0] = nil
|
||||
} else {
|
||||
oldn.children[1] = nil
|
||||
}
|
||||
}
|
||||
newn.children[0] = oldn.children[0]
|
||||
newn.children[1] = oldn.children[1]
|
||||
newn.parent = oldn.parent
|
||||
if oldn.parent != nil {
|
||||
if oldn.parent.children[0] == oldn {
|
||||
oldn.parent.children[0] = newn
|
||||
} else {
|
||||
oldn.parent.children[1] = newn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func tailReplaceNode(oldn, newn *tNode) {
|
||||
newn.children[0] = oldn.children[0]
|
||||
newn.children[1] = oldn.children[1]
|
||||
newn.parent = oldn.parent
|
||||
if oldn.parent != nil {
|
||||
if oldn.parent.children[0] == oldn {
|
||||
oldn.parent.children[0] = newn
|
||||
} else {
|
||||
oldn.parent.children[1] = newn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
678
priority_queue/vbt_test.go
Normal file
678
priority_queue/vbt_test.go
Normal file
|
@ -0,0 +1,678 @@
|
|||
package pqueue
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"474420502.top/eson/structure/compare"
|
||||
"github.com/huandu/skiplist"
|
||||
|
||||
"github.com/Pallinder/go-randomdata"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/emirpasic/gods/trees/avltree"
|
||||
"github.com/emirpasic/gods/trees/redblacktree"
|
||||
)
|
||||
|
||||
const CompareSize = 1000000
|
||||
const NumberMax = 50000000
|
||||
|
||||
func Save(t *testing.T) {
|
||||
|
||||
f, err := os.OpenFile("../l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
var l []int
|
||||
// for i := 0; len(l) < 1000; i++ {
|
||||
// v := randomdata.Number(0, 65535)
|
||||
// l = append(l, v)
|
||||
// }
|
||||
|
||||
//m := make(map[int]int)
|
||||
for i := 0; len(l) < CompareSize; i++ {
|
||||
v := randomdata.Number(0, NumberMax)
|
||||
// if _, ok := m[v]; !ok {
|
||||
// m[v] = v
|
||||
l = append(l, v)
|
||||
// }
|
||||
}
|
||||
|
||||
var result bytes.Buffer
|
||||
encoder := gob.NewEncoder(&result)
|
||||
encoder.Encode(l)
|
||||
lbytes := result.Bytes()
|
||||
f.Write(lbytes)
|
||||
|
||||
}
|
||||
|
||||
func loadTestData() []int {
|
||||
data, err := ioutil.ReadFile("../l.log")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
var l []int
|
||||
decoder := gob.NewDecoder(bytes.NewReader(data))
|
||||
decoder.Decode(&l)
|
||||
return l
|
||||
}
|
||||
|
||||
func TestIndexRange(t *testing.T) {
|
||||
tree := newVBT(compare.Int)
|
||||
l := []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15}
|
||||
for _, v := range l {
|
||||
tree.Put(v)
|
||||
}
|
||||
// [3 7 14 14 14 15 16 17 20 21 30 40 40 40 40 50]
|
||||
// t.Error(tree.Values(), tree.Size())
|
||||
|
||||
var result string
|
||||
result = spew.Sprint(tree.IndexRange(0, 5))
|
||||
if result != "[3 7 14 14 14 15] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(2, 5))
|
||||
if result != "[14 14 14 15] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(10, 100))
|
||||
if result != "[30 40 40 40 40 50] false" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(15, 0)) // size = 16, index max = 15
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(16, 0)) // size = 16, index max = 15
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] false" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(5, 1)) // size = 16, index max = 15
|
||||
if result != "[15 14 14 14 7] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(-1, -5)) // size = 16, index max = 15
|
||||
if result != "[50 40 40 40 40] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(-1, -16)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(-1, -17)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
if result != "[50 40 40 40 40 30 21 20 17 16 15 14 14 14 7 3] false" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = spew.Sprint(tree.IndexRange(-5, -1)) // size = 16, index max = 0 - 15 (-1,-16)
|
||||
if result != "[40 40 40 40 50] true" {
|
||||
t.Error(result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAround(t *testing.T) {
|
||||
tree := newVBT(compare.Int)
|
||||
for _, v := range []int{7, 14, 14, 14, 16, 17, 20, 30, 21, 40, 50, 3, 40, 40, 40, 15} {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
var Result string
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(17))
|
||||
if Result != "[16 17 20]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("17 is root, tree.GetAround(17)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(3))
|
||||
if Result != "[<nil> 3 7]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("tree.GetAround(3)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(40))
|
||||
if Result != "[30 40 40]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("tree.GetAround(40)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(50))
|
||||
if Result != "[40 50 <nil>]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("tree.GetAround(50)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(18))
|
||||
if Result != "[17 <nil> 20]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("18 is not in list, tree.GetAround(18)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(5))
|
||||
if Result != "[3 <nil> 7]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("5 is not in list, tree.GetAround(5)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(2))
|
||||
if Result != "[<nil> <nil> 3]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("2 is not in list, tree.GetAround(2)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
Result = spew.Sprint(tree.GetAround(100))
|
||||
if Result != "[50 <nil> <nil>]" {
|
||||
t.Error(tree.Values())
|
||||
t.Error("50 is not in list, tree.GetAround(50)) is error", Result)
|
||||
t.Error(tree.debugString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// // for test error case
|
||||
|
||||
func TestPutComparatorRandom(t *testing.T) {
|
||||
|
||||
for n := 0; n < 300000; n++ {
|
||||
tree := newVBT(compare.Int)
|
||||
godsavl := avltree.NewWithIntComparator()
|
||||
|
||||
content := ""
|
||||
m := make(map[int]int)
|
||||
for i := 0; len(m) < 10; i++ {
|
||||
v := randomdata.Number(0, 65535)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
content += spew.Sprint(v) + ","
|
||||
tree.Put(v)
|
||||
godsavl.Put(v, v)
|
||||
}
|
||||
}
|
||||
|
||||
s1 := spew.Sprint(tree.Values())
|
||||
s2 := spew.Sprint(godsavl.Values())
|
||||
|
||||
if s1 != s2 {
|
||||
t.Error(godsavl.String())
|
||||
t.Error(tree.debugString())
|
||||
t.Error(content, n)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tree := newVBT(compare.Int)
|
||||
for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
for _, v := range []int{2383, 7666, 3055, 39016, 57092, 27897, 36513, 1562, 22574, 23202} {
|
||||
v, ok := tree.Get(v)
|
||||
if !ok {
|
||||
t.Error("the val not found ", v)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := tree.Get(10000); ok {
|
||||
t.Error("the val(1000) is not in tree, but is found", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRange(t *testing.T) {
|
||||
tree := newVBT(compare.Int)
|
||||
for _, v := range []int{5, 6, 8, 10, 13, 17, 1, 2, 40, 30} {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
// t.Error(tree.debugString())
|
||||
// t.Error(tree.getArountNode(20))
|
||||
// t.Error(tree.Values())
|
||||
|
||||
result := tree.GetRange(0, 20)
|
||||
if spew.Sprint(result) != "[1 2 5 6 8 10 13 17]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(-5, -1)
|
||||
if spew.Sprint(result) != "[]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(7, 20)
|
||||
if spew.Sprint(result) != "[8 10 13 17]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(30, 40)
|
||||
if spew.Sprint(result) != "[30 40]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(30, 60)
|
||||
if spew.Sprint(result) != "[30 40]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(40, 40)
|
||||
if spew.Sprint(result) != "[40]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(50, 60)
|
||||
if spew.Sprint(result) != "[]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(50, 1)
|
||||
if spew.Sprint(result) != "[40 30 17 13 10 8 6 5 2 1]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
result = tree.GetRange(30, 20)
|
||||
if spew.Sprint(result) != "[30]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTravalsal(t *testing.T) {
|
||||
tree := newVBT(compare.Int)
|
||||
for _, v := range []int{5, 6, 8, 10, 13, 17, 1, 2, 40, 30} {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
i := 0
|
||||
var result []interface{}
|
||||
tree.Traversal(func(v interface{}) bool {
|
||||
result = append(result, v)
|
||||
i++
|
||||
if i >= 10 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if spew.Sprint(result) != "[1 2 5 6 8 10 13 17 30 40]" {
|
||||
t.Error(result)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
ALL:
|
||||
for c := 0; c < 5000; c++ {
|
||||
tree := newVBT(compare.Int)
|
||||
gods := avltree.NewWithIntComparator()
|
||||
var l []int
|
||||
m := make(map[int]int)
|
||||
|
||||
for i := 0; len(l) < 20; i++ {
|
||||
v := randomdata.Number(0, 100000)
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = v
|
||||
l = append(l, v)
|
||||
tree.Put(v)
|
||||
gods.Put(v, v)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
|
||||
tree.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
|
||||
s1 := spew.Sprint(tree.Values())
|
||||
s2 := spew.Sprint(gods.Values())
|
||||
if s1 != s2 {
|
||||
t.Error("avl remove error", "avlsize = ", tree.Size())
|
||||
t.Error(tree.root, i, l[i])
|
||||
t.Error(s1)
|
||||
t.Error(s2)
|
||||
break ALL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
|
||||
ALL:
|
||||
for N := 0; N < 5000; N++ {
|
||||
tree := newVBT(compare.Int)
|
||||
gods := avltree.NewWithIntComparator()
|
||||
|
||||
var l []int
|
||||
m := make(map[int]int)
|
||||
|
||||
for i := 0; len(l) < 20; i++ {
|
||||
v := randomdata.Number(0, 100)
|
||||
if _, ok := m[v]; !ok {
|
||||
l = append(l, v)
|
||||
m[v] = v
|
||||
tree.Put(v)
|
||||
gods.Put(v, v)
|
||||
}
|
||||
}
|
||||
|
||||
src1 := tree.String()
|
||||
src2 := gods.String()
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
tree.Remove(l[i])
|
||||
gods.Remove(l[i])
|
||||
if tree.root != nil && spew.Sprint(gods.Values()) != spew.Sprint(tree.Values()) {
|
||||
t.Error(src1)
|
||||
t.Error(src2)
|
||||
t.Error(tree.debugString())
|
||||
t.Error(gods.String())
|
||||
t.Error(l[i])
|
||||
break 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) {
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkIndexRange(b *testing.B) {
|
||||
tree := newVBT(compare.Int)
|
||||
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.IndexRange(i, i+49)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSkipListSet(b *testing.B) {
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
execCount := 1
|
||||
b.N = len(l) * execCount
|
||||
|
||||
for i := 0; i < execCount; i++ {
|
||||
sl := skiplist.New(skiplist.Int)
|
||||
for _, v := range l {
|
||||
sl.Set(v, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIterator(b *testing.B) {
|
||||
tree := newVBT(compare.Int)
|
||||
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
|
||||
for _, v := range l {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
iter := tree.Iterator()
|
||||
b.N = 0
|
||||
for iter.Next() {
|
||||
b.N++
|
||||
}
|
||||
for iter.Prev() {
|
||||
b.N++
|
||||
}
|
||||
for iter.Next() {
|
||||
b.N++
|
||||
}
|
||||
b.Log(b.N, len(l))
|
||||
}
|
||||
|
||||
func BenchmarkRemove(b *testing.B) {
|
||||
tree := newVBT(compare.Int)
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
b.N = len(l)
|
||||
for _, v := range l {
|
||||
tree.Put(v)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < len(l); i++ {
|
||||
tree.Remove(l[i])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGodsRemove(b *testing.B) {
|
||||
tree := avltree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
b.N = len(l)
|
||||
for _, v := range l {
|
||||
tree.Put(v, v)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < len(l); i++ {
|
||||
tree.Remove(l[i])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGodsRBRemove(b *testing.B) {
|
||||
tree := redblacktree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
b.N = len(l)
|
||||
for _, v := range l {
|
||||
tree.Put(v, v)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < len(l); i++ {
|
||||
tree.Remove(l[i])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGet(b *testing.B) {
|
||||
|
||||
tree := newVBT(compare.Int)
|
||||
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
for i := 0; i < b.N; i++ {
|
||||
tree.Put(l[i])
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
execCount := 10
|
||||
b.N = len(l) * execCount
|
||||
|
||||
for i := 0; i < execCount; i++ {
|
||||
for _, v := range l {
|
||||
tree.Get(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGodsRBGet(b *testing.B) {
|
||||
tree := redblacktree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
for i := 0; i < b.N; i++ {
|
||||
tree.Put(l[i], i)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
execCount := 10
|
||||
b.N = len(l) * execCount
|
||||
|
||||
for i := 0; i < execCount; i++ {
|
||||
for _, v := range l {
|
||||
tree.Get(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGodsAvlGet(b *testing.B) {
|
||||
tree := avltree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
for i := 0; i < b.N; i++ {
|
||||
tree.Put(l[i], i)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
execCount := 10
|
||||
b.N = len(l) * execCount
|
||||
|
||||
for i := 0; i < execCount; i++ {
|
||||
for _, v := range l {
|
||||
tree.Get(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPut(b *testing.B) {
|
||||
l := loadTestData()
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
execCount := 10
|
||||
b.N = len(l) * execCount
|
||||
for i := 0; i < execCount; i++ {
|
||||
tree := newVBT(compare.Int)
|
||||
for _, v := range l {
|
||||
tree.Put(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPutStable(t *testing.T) {
|
||||
tree := newVBT(compare.Int)
|
||||
for i := 0; i < 10; i++ {
|
||||
v := randomdata.Number(0, 100)
|
||||
tree.Put(v)
|
||||
t.Error(tree.debugString(), v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkIndex(b *testing.B) {
|
||||
tree := newVBT(compare.Int)
|
||||
|
||||
l := loadTestData()
|
||||
b.N = len(l)
|
||||
for i := 0; i < b.N; i++ {
|
||||
tree.Put(l[i])
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
tree.Index(i)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGodsRBPut(b *testing.B) {
|
||||
tree := redblacktree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
b.N = len(l)
|
||||
for _, v := range l {
|
||||
tree.Put(v, v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGodsPut(b *testing.B) {
|
||||
tree := avltree.NewWithIntComparator()
|
||||
|
||||
l := loadTestData()
|
||||
|
||||
b.ResetTimer()
|
||||
b.StartTimer()
|
||||
|
||||
b.N = len(l)
|
||||
for _, v := range l {
|
||||
tree.Put(v, v)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user