focus/tree/lsv/itree.go
huangsimin 1eb9512a5f TODO
2020-03-20 18:08:02 +08:00

494 lines
9.9 KiB
Go

package lsv
// INode 用于索引的节点
type INode struct {
family [3]*INode
size int
tree *DTree
}
// NewINode 生成inode节点
func NewINode() *INode {
inode := &INode{}
inode.size = 1
inode.tree = newDataTree(compareRunes)
return inode
}
// ITree 用于索引的树
type ITree struct {
root *INode
limit int
Compare func(s1, s2 []rune) int
}
// New 生成一颗索引树
func New(Compare func(s1, s2 []rune) int) *ITree {
return &ITree{Compare: Compare, limit: 100}
}
// Put return bool
func (tree *ITree) Put(key, value []rune) (isInsert bool) {
// node := &INode{key: key, value: value, size: 1}
if tree.root == nil {
tree.root = NewINode()
return tree.root.tree.Put(key, value)
}
for cur := tree.root; ; {
if cur.size > 8 {
factor := cur.size / 10 // or factor = 1
ls, rs := cur.family[1].size, cur.family[2].size
if rs >= ls*2+factor || ls >= rs*2+factor {
tree.ifixSize(cur, ls, rs)
}
}
c := tree.Compare(key, cur.tree.feature.key)
switch {
case c < 0:
if cur.family[1] == nil {
if cur.tree.root.size >= tree.limit {
// 子树的节点分解 操作
lspilt := cur.tree.root.family[1]
rspilt := cur.tree.root.family[2]
// 根树 新节点要插入到 右节点的最小值位置 即是 左~
irnode := NewINode()
irnode.tree.root = rspilt
irnode.tree.feature = cur.tree.feature
icur := cur.family[2]
if icur == nil {
cur.family[2] = irnode
} else {
for ; icur.family[1] != nil; icur = icur.family[1] {
}
icur.family[1] = irnode
irnode.family[0] = icur
for temp := icur; temp != nil; temp = temp.family[0] {
temp.size++
}
// 调整3节点失衡的情况
if cur.family[0] != nil && cur.family[0].size == 3 {
if cur.family[0].family[1] == nil {
tree.ilrrotate3(cur.family[0])
} else {
tree.irrotate3(cur.family[0])
}
}
}
rspilt.family[0] = nil
tempRoot := cur.tree.root
lspilt.family[0] = nil
cur.tree.root = lspilt
tempRoot.size = 1
for i := 1; i < len(tempRoot.family); i++ {
tempRoot.family[i] = nil
}
cur.tree.putfeature(tempRoot)
}
return cur.tree.Put(key, value)
// inode := NewINode()
// cur.family[1] = inode
// inode.family[0] = cur
// for temp := cur; temp != nil; temp = temp.family[0] {
// temp.size++
// }
// if cur.family[0] != nil && cur.family[0].size == 3 {
// if cur.family[0].family[1] == nil {
// tree.ilrrotate3(cur.family[0])
// } else {
// tree.irrotate3(cur.family[0])
// }
// }
// return true
}
cur = cur.family[1]
case c > 0:
if cur.family[2] == nil {
if cur.tree.root.size >= tree.limit {
lspilt := cur.tree.root.family[1]
rspilt := cur.tree.root.family[2]
// cur.family
irnode := NewINode()
irnode.tree.root = rspilt
icur := cur.family[2]
if icur == nil {
cur.family[2] = irnode
} else {
for ; icur.family[1] != nil; icur = icur.family[1] {
}
icur.family[1] = irnode
irnode.family[0] = icur
for temp := icur; temp != nil; temp = temp.family[0] {
temp.size++
}
// 调整3节点失衡的情况
if icur.family[0] != nil && icur.family[0].size == 3 {
if icur.family[0].family[2] == nil {
tree.irlrotate3(icur.family[0])
} else {
tree.ilrotate3(icur.family[0])
}
}
}
rspilt.family[0] = nil
// cur.family irnode
tempRoot := cur.tree.root
lspilt.family[0] = nil
cur.tree.root = lspilt
tempRoot.size = 1
for i := 1; i < len(tempRoot.family); i++ {
tempRoot.family[i] = nil
}
cur.tree.putfeature(tempRoot)
}
return cur.tree.Put(key, value)
// inode := NewINode()
// cur.family[2] = inode
// inode.family[0] = cur
// for temp := cur; temp != nil; temp = temp.family[0] {
// temp.size++
// }
// if cur.family[0] != nil && cur.family[0].size == 3 {
// if cur.family[0].family[2] == nil {
// tree.irlrotate3(cur.family[0])
// } else {
// tree.ilrotate3(cur.family[0])
// }
// }
// return true
}
cur = cur.family[2]
default:
return cur.tree.Put(key, value)
}
}
}
func (tree *ITree) String() {
}
func (tree *ITree) ifixSize(cur *INode, ls, rs int) {
if ls > rs {
llsize, lrsize := igetChildrenSize(cur.family[1])
if lrsize > llsize {
tree.irlrotate(cur)
} else {
tree.irrotate(cur)
}
} else {
rlsize, rrsize := igetChildrenSize(cur.family[2])
if rlsize > rrsize {
tree.ilrrotate(cur)
} else {
tree.ilrotate(cur)
}
}
}
func (tree *ITree) ilrrotate3(cur *INode) {
const l = 2
const r = 1
movparent := cur.family[l]
mov := movparent.family[r]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
cur.family[r] = mov
mov.family[0] = cur
cur.family[l] = movparent
movparent.family[r] = nil
cur.family[r] = mov
mov.family[0] = cur
cur.family[l].size = 1
}
func (tree *ITree) ilrrotate(cur *INode) {
const l = 2
const r = 1
movparent := cur.family[l]
mov := movparent.family[r]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
if mov.family[l] != nil {
movparent.family[r] = mov.family[l]
movparent.family[r].family[0] = movparent
//movparent.family[r].child = l
} else {
movparent.family[r] = nil
}
if mov.family[r] != nil {
mov.family[l] = mov.family[r]
//mov.family[l].child = l
} else {
mov.family[l] = nil
}
if cur.family[r] != nil {
mov.family[r] = cur.family[r]
mov.family[r].family[0] = mov
} else {
mov.family[r] = nil
}
cur.family[r] = mov
mov.family[0] = cur
movparent.size = igetChildrenSumSize(movparent) + 1
mov.size = igetChildrenSumSize(mov) + 1
cur.size = igetChildrenSumSize(cur) + 1
}
func (tree *ITree) irlrotate3(cur *INode) {
const l = 1
const r = 2
movparent := cur.family[l]
mov := movparent.family[r]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
cur.family[r] = mov
mov.family[0] = cur
cur.family[l] = movparent
movparent.family[r] = nil
cur.family[r] = mov
mov.family[0] = cur
// cur.size = 3
// cur.family[r].size = 1
cur.family[l].size = 1
}
func (tree *ITree) irlrotate(cur *INode) {
const l = 1
const r = 2
movparent := cur.family[l]
mov := movparent.family[r]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
if mov.family[l] != nil {
movparent.family[r] = mov.family[l]
movparent.family[r].family[0] = movparent
} else {
movparent.family[r] = nil
}
if mov.family[r] != nil {
mov.family[l] = mov.family[r]
} else {
mov.family[l] = nil
}
if cur.family[r] != nil {
mov.family[r] = cur.family[r]
mov.family[r].family[0] = mov
} else {
mov.family[r] = nil
}
cur.family[r] = mov
mov.family[0] = cur
movparent.size = igetChildrenSumSize(movparent) + 1
mov.size = igetChildrenSumSize(mov) + 1
cur.size = igetChildrenSumSize(cur) + 1
}
func (tree *ITree) irrotate3(cur *INode) {
const l = 1
const r = 2
// 1 right 0 left
mov := cur.family[l]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
cur.family[r] = mov
cur.family[l] = mov.family[l]
cur.family[l].family[0] = cur
mov.family[l] = nil
mov.size = 1
}
func (tree *ITree) irrotate(cur *INode) {
const l = 1
const r = 2
// 1 right 0 left
mov := cur.family[l]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
// mov.family[l]不可能为nil
mov.family[l].family[0] = cur
cur.family[l] = mov.family[l]
// 解决mov节点孩子转移的问题
if mov.family[r] != nil {
mov.family[l] = mov.family[r]
} else {
mov.family[l] = nil
}
if cur.family[r] != nil {
mov.family[r] = cur.family[r]
mov.family[r].family[0] = mov
} else {
mov.family[r] = nil
}
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
cur.family[r] = mov
mov.size = igetChildrenSumSize(mov) + 1
cur.size = igetChildrenSumSize(cur) + 1
}
func (tree *ITree) ilrotate3(cur *INode) {
const l = 2
const r = 1
// 1 right 0 left
mov := cur.family[l]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
cur.family[r] = mov
cur.family[l] = mov.family[l]
cur.family[l].family[0] = cur
mov.family[l] = nil
mov.size = 1
}
func (tree *ITree) ilrotate(cur *INode) {
const l = 2
const r = 1
// 1 right 0 left
mov := cur.family[l]
mov.tree, cur.tree = cur.tree, mov.tree //交换值达到, 相对位移
// mov.family[l]不可能为nil
mov.family[l].family[0] = cur
cur.family[l] = mov.family[l]
// 解决mov节点孩子转移的问题
if mov.family[r] != nil {
mov.family[l] = mov.family[r]
} else {
mov.family[l] = nil
}
if cur.family[r] != nil {
mov.family[r] = cur.family[r]
mov.family[r].family[0] = mov
} else {
mov.family[r] = nil
}
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
cur.family[r] = mov
mov.size = igetChildrenSumSize(mov) + 1
cur.size = igetChildrenSumSize(cur) + 1
}
func igetChildrenSumSize(cur *INode) int {
return igetSize(cur.family[1]) + igetSize(cur.family[2])
}
func igetChildrenSize(cur *INode) (int, int) {
return igetSize(cur.family[1]), igetSize(cur.family[2])
}
func igetSize(cur *INode) int {
if cur == nil {
return 0
}
return cur.size
}
func (tree *ITree) ifixSizeWithRemove(cur *INode) {
for cur != nil {
cur.size--
if cur.size > 8 {
factor := cur.size / 10 // or factor = 1
ls, rs := igetChildrenSize(cur)
if rs >= ls*2+factor || ls >= rs*2+factor {
tree.ifixSize(cur, ls, rs)
}
} else if cur.size == 3 {
if cur.family[1] == nil {
if cur.family[2].family[1] == nil {
tree.ilrotate3(cur)
} else {
tree.ilrrotate3(cur)
}
} else if cur.family[2] == nil {
if cur.family[1].family[2] == nil {
tree.irrotate3(cur)
} else {
tree.irlrotate3(cur)
}
}
}
cur = cur.family[0]
}
}