222 lines
4.1 KiB
Go
222 lines
4.1 KiB
Go
package hashmap
|
|
|
|
import (
|
|
"474420502.top/eson/structure/compare"
|
|
)
|
|
|
|
type avlNode struct {
|
|
children [2]*avlNode
|
|
hash uint
|
|
key, value interface{}
|
|
}
|
|
|
|
type avlTree struct {
|
|
root *avlNode
|
|
lsize, rsize int
|
|
Compare compare.Compare
|
|
}
|
|
|
|
func avlNew(Compare compare.Compare) *avlTree {
|
|
return &avlTree{Compare: Compare}
|
|
}
|
|
|
|
func (tree *avlTree) Clear() {
|
|
tree.lsize, tree.rsize = 0, 0
|
|
tree.root = nil
|
|
}
|
|
|
|
// func (tree *avlTree) Size() int {
|
|
// return tree.lsize + tree.rsize + 1
|
|
// }
|
|
|
|
// func (tree *avlTree) Remove(key interface{}) (interface{}, bool) {
|
|
|
|
// if n, ok := tree.GetNode(key); ok {
|
|
|
|
// tree.size--
|
|
// if tree.size == 0 {
|
|
// tree.root = nil
|
|
// return n.value, true
|
|
// }
|
|
|
|
// left := getHeight(n.children[0])
|
|
// right := getHeight(n.children[1])
|
|
|
|
// if left == -1 && right == -1 {
|
|
// p := n.parent
|
|
// p.children[getRelationship(n)] = nil
|
|
// tree.fixRemoveHeight(p)
|
|
// return n.value, true
|
|
// }
|
|
|
|
// var cur *avlNode
|
|
// if left > right {
|
|
// cur = n.children[0]
|
|
// for cur.children[1] != nil {
|
|
// cur = cur.children[1]
|
|
// }
|
|
|
|
// cleft := cur.children[0]
|
|
// cur.parent.children[getRelationship(cur)] = cleft
|
|
// if cleft != nil {
|
|
// cleft.parent = cur.parent
|
|
// }
|
|
|
|
// } else {
|
|
// cur = n.children[1]
|
|
// for cur.children[0] != nil {
|
|
// cur = cur.children[0]
|
|
// }
|
|
|
|
// cright := cur.children[1]
|
|
// cur.parent.children[getRelationship(cur)] = cright
|
|
|
|
// if cright != nil {
|
|
// cright.parent = cur.parent
|
|
// }
|
|
// }
|
|
|
|
// cparent := cur.parent
|
|
// // 修改为interface 交换
|
|
// n.value, cur.value = cur.value, n.value
|
|
// n.key, cur.key = cur.key, n.key
|
|
|
|
// // 考虑到刚好替换的节点是 被替换节点的孩子节点的时候, 从自身修复高度
|
|
// if cparent == n {
|
|
// tree.fixRemoveHeight(n)
|
|
// } else {
|
|
// tree.fixRemoveHeight(cparent)
|
|
// }
|
|
|
|
// return cur.value, true
|
|
// }
|
|
|
|
// return nil, false
|
|
// }
|
|
|
|
func (tree *avlTree) Get(key interface{}) (interface{}, bool) {
|
|
n, ok := tree.GetNode(key)
|
|
if ok {
|
|
return n.value, true
|
|
}
|
|
return n, false
|
|
}
|
|
|
|
func (tree *avlTree) GetNode(key interface{}) (*avlNode, bool) {
|
|
|
|
for n := tree.root; n != nil; {
|
|
switch c := tree.Compare(key, n.key); c {
|
|
case -1:
|
|
n = n.children[0]
|
|
case 1:
|
|
n = n.children[1]
|
|
case 0:
|
|
return n, true
|
|
default:
|
|
panic("Get Compare only is allowed in -1, 0, 1")
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (tree *avlTree) PutNode(pnode *avlNode) bool {
|
|
|
|
pnode.children[0] = nil
|
|
pnode.children[1] = nil
|
|
// pnode.parent = nil
|
|
|
|
if tree.root == nil {
|
|
// tree.size++
|
|
tree.root = pnode
|
|
return true
|
|
}
|
|
|
|
for cur, c := tree.root, 0; ; {
|
|
c = tree.Compare(pnode.key, cur.key)
|
|
if c == -1 {
|
|
if cur.children[0] == nil {
|
|
// tree.size++
|
|
cur.children[0] = pnode
|
|
return true
|
|
}
|
|
cur = cur.children[0]
|
|
} else if c == 1 {
|
|
if cur.children[1] == nil {
|
|
cur.children[1] = pnode
|
|
return true
|
|
}
|
|
cur = cur.children[1]
|
|
} else {
|
|
cur.key = pnode.key
|
|
cur.value = pnode.value
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
func (tree *avlTree) Put(key, value interface{}) bool {
|
|
|
|
if tree.root == nil {
|
|
tree.root = &avlNode{key: key, value: value}
|
|
return true
|
|
}
|
|
|
|
for cur, c := tree.root, 0; ; {
|
|
c = tree.Compare(key, cur.key)
|
|
if c == -1 {
|
|
if cur.children[0] == nil {
|
|
cur.children[0] = &avlNode{key: key, value: value}
|
|
return true
|
|
}
|
|
cur = cur.children[0]
|
|
} else if c == 1 {
|
|
if cur.children[1] == nil {
|
|
cur.children[1] = &avlNode{key: key, value: value}
|
|
return true
|
|
}
|
|
cur = cur.children[1]
|
|
} else {
|
|
cur.key = key
|
|
cur.value = value
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
func (tree *avlTree) lrrotate(cur *avlNode) {
|
|
|
|
const l = 1
|
|
const r = 0
|
|
|
|
}
|
|
|
|
func (tree *avlTree) rlrotate(cur *avlNode) {
|
|
|
|
const l = 0
|
|
const r = 1
|
|
|
|
}
|
|
|
|
func (tree *avlTree) rrotate(cur *avlNode) {
|
|
|
|
const l = 0
|
|
const r = 1
|
|
// 1 right 0 left
|
|
mov := cur.children[l]
|
|
|
|
mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
|
mov.key, cur.key = cur.key, mov.key
|
|
|
|
}
|
|
|
|
func (tree *avlTree) lrotate(cur *avlNode) {
|
|
|
|
const l = 1
|
|
const r = 0
|
|
|
|
mov := cur.children[l]
|
|
|
|
mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移
|
|
mov.key, cur.key = cur.key, mov.key
|
|
}
|