u
This commit is contained in:
+243
@@ -0,0 +1,243 @@
|
||||
package avl
|
||||
|
||||
import "cmp"
|
||||
|
||||
// avl.go
|
||||
// 泛型 AVL 自平衡二叉搜索树。
|
||||
//
|
||||
// 约定:空子树高度为 0,叶子高度为 1;不插入重复值。
|
||||
// 每次插入或删除后,都要更新 Height,再按 LL/LR/RR/RL 四种情况重平衡。
|
||||
|
||||
// AVLNode AVL 树节点。Height 是以该节点为根的子树高度。
|
||||
type AVLNode[T cmp.Ordered] struct {
|
||||
Val T
|
||||
Left *AVLNode[T]
|
||||
Right *AVLNode[T]
|
||||
Height int
|
||||
}
|
||||
|
||||
// AVLTree AVL 自平衡二叉搜索树。
|
||||
type AVLTree[T cmp.Ordered] struct {
|
||||
Root *AVLNode[T]
|
||||
}
|
||||
|
||||
// NewAVLTree 创建一棵空 AVL 树。
|
||||
func NewAVLTree[T cmp.Ordered]() *AVLTree[T] {
|
||||
return &AVLTree[T]{}
|
||||
}
|
||||
|
||||
// Insert 插入 v;重复值不插入。
|
||||
func (t *AVLTree[T]) Insert(v T) {
|
||||
var insert func(node *AVLNode[T]) *AVLNode[T]
|
||||
insert = func(node *AVLNode[T]) *AVLNode[T] {
|
||||
if node == nil {
|
||||
return &AVLNode[T]{Val: v, Height: 1}
|
||||
}
|
||||
if v == node.Val {
|
||||
return node
|
||||
} else if v < node.Val {
|
||||
node.Left = insert(node.Left)
|
||||
} else {
|
||||
node.Right = insert(node.Right)
|
||||
}
|
||||
node.Height = t.calculateHeight(node)
|
||||
return t.balancing(node)
|
||||
}
|
||||
t.Root = insert(t.Root)
|
||||
}
|
||||
|
||||
func (t *AVLTree[T]) balancing(node *AVLNode[T]) *AVLNode[T] {
|
||||
bf := t.calculateBF(node)
|
||||
if bf < -1 {
|
||||
// 右重 R
|
||||
_bf := t.calculateBF(node.Right)
|
||||
if _bf <= 0 {
|
||||
// RR:左旋自身
|
||||
return t.rotateLeft(node)
|
||||
}
|
||||
if _bf > 0 {
|
||||
// RL: 右旋右孩子再左旋自身
|
||||
node.Right = t.rotateRight(node.Right)
|
||||
return t.rotateLeft(node)
|
||||
}
|
||||
}
|
||||
if bf > 1 {
|
||||
// 左重 L
|
||||
_bf := t.calculateBF(node.Left)
|
||||
if _bf >= 0 {
|
||||
// LL: 右旋自身
|
||||
return t.rotateRight(node)
|
||||
}
|
||||
if _bf < 0 {
|
||||
// LR: 左旋左孩子再右旋自身
|
||||
node.Left = t.rotateLeft(node.Left)
|
||||
return t.rotateRight(node)
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func (t *AVLTree[T]) calculateHeight(node *AVLNode[T]) int {
|
||||
if node == nil {
|
||||
return 0
|
||||
}
|
||||
l, r := 0, 0
|
||||
if node.Left != nil {
|
||||
l = node.Left.Height
|
||||
}
|
||||
if node.Right != nil {
|
||||
r = node.Right.Height
|
||||
}
|
||||
return max(l, r) + 1
|
||||
}
|
||||
|
||||
func (t *AVLTree[T]) calculateBF(node *AVLNode[T]) int {
|
||||
if node == nil {
|
||||
return 0
|
||||
}
|
||||
leftHeight, rightHeight := 0, 0
|
||||
if node.Left != nil {
|
||||
leftHeight = node.Left.Height
|
||||
}
|
||||
if node.Right != nil {
|
||||
rightHeight = node.Right.Height
|
||||
}
|
||||
bf := leftHeight - rightHeight
|
||||
return bf
|
||||
}
|
||||
|
||||
// rotateLeft 对 node 左旋,返回旋转后的新子树根。
|
||||
//
|
||||
// node right
|
||||
// / \ / \
|
||||
// A right → node C
|
||||
// / \ / \
|
||||
// B C A B
|
||||
//
|
||||
// B 的值介于 node 和 right 之间,因此旋转后要接到 node.Right。
|
||||
func (t *AVLTree[T]) rotateLeft(node *AVLNode[T]) *AVLNode[T] {
|
||||
rNode := node.Right
|
||||
node.Right = rNode.Left
|
||||
rNode.Left = node
|
||||
node.Height = t.calculateHeight(node)
|
||||
rNode.Height = t.calculateHeight(rNode)
|
||||
return rNode
|
||||
}
|
||||
|
||||
// rotateRight 对 node 右旋,返回旋转后的新子树根。
|
||||
//
|
||||
// node left
|
||||
// / \ / \
|
||||
// left C → A node
|
||||
// / \ / \
|
||||
// A B B C
|
||||
//
|
||||
// B 的值介于 left 和 node 之间,因此旋转后要接到 node.Left。
|
||||
func (t *AVLTree[T]) rotateRight(node *AVLNode[T]) *AVLNode[T] {
|
||||
lNode := node.Left
|
||||
node.Left = lNode.Right
|
||||
lNode.Right = node
|
||||
node.Height = t.calculateHeight(node)
|
||||
lNode.Height = t.calculateHeight(lNode)
|
||||
return lNode
|
||||
}
|
||||
|
||||
func (t *AVLTree[T]) Inorder() []T {
|
||||
res := []T{}
|
||||
var helper func(node *AVLNode[T])
|
||||
helper = func(node *AVLNode[T]) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
helper(node.Left)
|
||||
res = append(res, node.Val)
|
||||
helper(node.Right)
|
||||
}
|
||||
helper(t.Root)
|
||||
return res
|
||||
}
|
||||
|
||||
// Search 查找 v 是否存在。只读操作,不需要更新高度或旋转。
|
||||
func (t *AVLTree[T]) Search(v T) bool {
|
||||
node := t.Root
|
||||
for node != nil {
|
||||
if node.Val == v {
|
||||
return true
|
||||
}
|
||||
if v < node.Val {
|
||||
node = node.Left
|
||||
} else {
|
||||
node = node.Right
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Height 返回整棵树的高度;空树为 0。
|
||||
func (t *AVLTree[T]) Height() int {
|
||||
if t.Root == nil {
|
||||
return 0
|
||||
}
|
||||
return t.Root.Height
|
||||
}
|
||||
|
||||
// Min 返回最小值及其是否存在。
|
||||
func (t *AVLTree[T]) Min() (T, bool) {
|
||||
node := t.Root
|
||||
if node == nil {
|
||||
var zero T
|
||||
return zero, false
|
||||
}
|
||||
for node.Left != nil {
|
||||
node = node.Left
|
||||
}
|
||||
return node.Val, true
|
||||
}
|
||||
|
||||
// Max 返回最大值及其是否存在。
|
||||
func (t *AVLTree[T]) Max() (T, bool) {
|
||||
node := t.Root
|
||||
if node == nil {
|
||||
var zero T
|
||||
return zero, false
|
||||
}
|
||||
for node.Right != nil {
|
||||
node = node.Right
|
||||
}
|
||||
return node.Val, true
|
||||
}
|
||||
|
||||
// Delete 删除 v;若 v 不存在,树保持不变。
|
||||
func (t *AVLTree[T]) Delete(v T) {
|
||||
var deleteNode func(node *AVLNode[T], target T) *AVLNode[T]
|
||||
deleteNode = func(node *AVLNode[T], target T) *AVLNode[T] {
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
if target < node.Val {
|
||||
node.Left = deleteNode(node.Left, target)
|
||||
} else if target > node.Val {
|
||||
node.Right = deleteNode(node.Right, target)
|
||||
} else {
|
||||
if node.Left == nil && node.Right != nil {
|
||||
return node.Right
|
||||
}
|
||||
if node.Left != nil && node.Right == nil {
|
||||
return node.Left
|
||||
}
|
||||
if node.Left != nil && node.Right != nil {
|
||||
n := node.Right
|
||||
for n.Left != nil {
|
||||
n = n.Left
|
||||
}
|
||||
node.Val = n.Val
|
||||
node.Right = deleteNode(node.Right, n.Val)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
node.Height = t.calculateHeight(node)
|
||||
return t.balancing(node)
|
||||
}
|
||||
t.Root = deleteNode(t.Root, v)
|
||||
}
|
||||
Reference in New Issue
Block a user