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)
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
package avl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAVLBasicOperations(t *testing.T) {
|
||||
tree := NewAVLTree[int]()
|
||||
|
||||
if tree.Height() != 0 {
|
||||
t.Fatalf("空树 Height() = %d, want 0", tree.Height())
|
||||
}
|
||||
if _, ok := tree.Min(); ok {
|
||||
t.Fatal("空树 Min() 的 ok = true, want false")
|
||||
}
|
||||
if _, ok := tree.Max(); ok {
|
||||
t.Fatal("空树 Max() 的 ok = true, want false")
|
||||
}
|
||||
if tree.Search(1) {
|
||||
t.Fatal("空树 Search(1) = true, want false")
|
||||
}
|
||||
|
||||
for _, v := range []int{6, 3, 2, 1, 4, 5} {
|
||||
tree.Insert(v)
|
||||
}
|
||||
|
||||
if got, want := tree.Inorder(), []int{1, 2, 3, 4, 5, 6}; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("Inorder() = %v, want %v", got, want)
|
||||
}
|
||||
if !tree.Search(1) || !tree.Search(6) || tree.Search(7) {
|
||||
t.Fatalf("Search 结果不正确:Search(1)=%v, Search(6)=%v, Search(7)=%v", tree.Search(1), tree.Search(6), tree.Search(7))
|
||||
}
|
||||
if got, ok := tree.Min(); !ok || got != 1 {
|
||||
t.Fatalf("Min() = (%d, %v), want (1, true)", got, ok)
|
||||
}
|
||||
if got, ok := tree.Max(); !ok || got != 6 {
|
||||
t.Fatalf("Max() = (%d, %v), want (6, true)", got, ok)
|
||||
}
|
||||
assertAVL(t, tree.Root, nil, nil)
|
||||
}
|
||||
|
||||
func TestAVLDelete(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
values []int
|
||||
delete int
|
||||
want []int
|
||||
wantMin *int
|
||||
wantMax *int
|
||||
}{
|
||||
{
|
||||
name: "delete only root leaf",
|
||||
values: []int{10},
|
||||
delete: 10,
|
||||
want: []int{},
|
||||
},
|
||||
{
|
||||
name: "delete root with one child",
|
||||
values: []int{10, 5},
|
||||
delete: 10,
|
||||
want: []int{5},
|
||||
wantMin: intPtr(5),
|
||||
wantMax: intPtr(5),
|
||||
},
|
||||
{
|
||||
name: "delete non-root leaf and update parent height",
|
||||
values: []int{10, 5, 15},
|
||||
delete: 5,
|
||||
want: []int{10, 15},
|
||||
wantMin: intPtr(10),
|
||||
wantMax: intPtr(15),
|
||||
},
|
||||
{
|
||||
name: "delete non-root with one child",
|
||||
values: []int{10, 5, 15, 12},
|
||||
delete: 15,
|
||||
want: []int{5, 10, 12},
|
||||
wantMin: intPtr(5),
|
||||
wantMax: intPtr(12),
|
||||
},
|
||||
{
|
||||
name: "delete root with two children successor is leaf",
|
||||
values: []int{10, 5, 15, 12, 18},
|
||||
delete: 10,
|
||||
want: []int{5, 12, 15, 18},
|
||||
wantMin: intPtr(5),
|
||||
wantMax: intPtr(18),
|
||||
},
|
||||
{
|
||||
name: "delete root with two children successor has right child",
|
||||
values: []int{10, 5, 20, 15, 25, 17},
|
||||
delete: 10,
|
||||
want: []int{5, 15, 17, 20, 25},
|
||||
wantMin: intPtr(5),
|
||||
wantMax: intPtr(25),
|
||||
},
|
||||
{
|
||||
name: "delete missing value leaves tree unchanged",
|
||||
values: []int{10, 5, 20, 15, 25},
|
||||
delete: 99,
|
||||
want: []int{5, 10, 15, 20, 25},
|
||||
wantMin: intPtr(5),
|
||||
wantMax: intPtr(25),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tree := NewAVLTree[int]()
|
||||
for _, v := range tc.values {
|
||||
tree.Insert(v)
|
||||
}
|
||||
|
||||
tree.Delete(tc.delete)
|
||||
|
||||
if got := tree.Inorder(); !reflect.DeepEqual(got, tc.want) {
|
||||
t.Fatalf("Delete(%d) 后 Inorder() = %v, want %v", tc.delete, got, tc.want)
|
||||
}
|
||||
if tree.Search(tc.delete) && tc.delete != 99 {
|
||||
t.Fatalf("Delete(%d) 后 Search(%d) = true, want false", tc.delete, tc.delete)
|
||||
}
|
||||
if tc.wantMin == nil {
|
||||
if tree.Height() != 0 {
|
||||
t.Fatalf("删空树后 Height() = %d, want 0", tree.Height())
|
||||
}
|
||||
if _, ok := tree.Min(); ok {
|
||||
t.Fatal("删空树后 Min() 的 ok = true, want false")
|
||||
}
|
||||
if _, ok := tree.Max(); ok {
|
||||
t.Fatal("删空树后 Max() 的 ok = true, want false")
|
||||
}
|
||||
} else {
|
||||
if got, ok := tree.Min(); !ok || got != *tc.wantMin {
|
||||
t.Fatalf("Min() = (%d, %v), want (%d, true)", got, ok, *tc.wantMin)
|
||||
}
|
||||
if got, ok := tree.Max(); !ok || got != *tc.wantMax {
|
||||
t.Fatalf("Max() = (%d, %v), want (%d, true)", got, ok, *tc.wantMax)
|
||||
}
|
||||
}
|
||||
assertAVL(t, tree.Root, nil, nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVLDeleteRebalancesOnPathToRoot(t *testing.T) {
|
||||
tree := NewAVLTree[int]()
|
||||
for _, v := range []int{4, 2, 6, 1, 3, 5, 7} {
|
||||
tree.Insert(v)
|
||||
}
|
||||
|
||||
for _, v := range []int{7, 6, 5} {
|
||||
tree.Delete(v)
|
||||
assertAVL(t, tree.Root, nil, nil)
|
||||
}
|
||||
|
||||
if got, want := tree.Inorder(), []int{1, 2, 3, 4}; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("连续删除后 Inorder() = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func assertAVL(t *testing.T, node *AVLNode[int], lower, upper *int) int {
|
||||
t.Helper()
|
||||
if node == nil {
|
||||
return 0
|
||||
}
|
||||
if lower != nil && node.Val <= *lower {
|
||||
t.Fatalf("BST 性质被破坏:节点 %d <= 下界 %d", node.Val, *lower)
|
||||
}
|
||||
if upper != nil && node.Val >= *upper {
|
||||
t.Fatalf("BST 性质被破坏:节点 %d >= 上界 %d", node.Val, *upper)
|
||||
}
|
||||
|
||||
leftHeight := assertAVL(t, node.Left, lower, &node.Val)
|
||||
rightHeight := assertAVL(t, node.Right, &node.Val, upper)
|
||||
if balanceFactor := leftHeight - rightHeight; balanceFactor < -1 || balanceFactor > 1 {
|
||||
t.Fatalf("节点 %d 的 BF = %d, want [-1, 1]", node.Val, balanceFactor)
|
||||
}
|
||||
|
||||
wantHeight := max(leftHeight, rightHeight) + 1
|
||||
if node.Height != wantHeight {
|
||||
t.Fatalf("节点 %d 的 Height = %d, want %d", node.Val, node.Height, wantHeight)
|
||||
}
|
||||
return wantHeight
|
||||
}
|
||||
|
||||
func intPtr(v int) *int {
|
||||
return &v
|
||||
}
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
package avl
|
||||
|
||||
import "fmt"
|
||||
|
||||
// AVL 自平衡二叉搜索树 —— 正确实现参考
|
||||
//
|
||||
// 核心设计点(对比你原文件里的 4 个 bug):
|
||||
// 1. 节点维护 Height,平衡因子 BF = height(Left) - height(Right);合法范围 {-1,0,1}
|
||||
// 2. 旋转函数【返回新子树根】,调用方用返回值接回父节点的 Left/Right
|
||||
// —— 这解决了"旋转接不回去"的根本问题
|
||||
// 3. 失衡判定看【子节点的 BF】,区分 LL/RR/LR/RL 四种 case,不是只看自己 BF
|
||||
// 4. 不用全局 depthIncre flag,递归返回新根,height 直接从子节点算
|
||||
|
||||
type Node struct {
|
||||
Val int
|
||||
Left *Node
|
||||
Right *Node
|
||||
Height int // 以该节点为根的子树高度;空节点=0,叶子=1
|
||||
}
|
||||
|
||||
func height(n *Node) int {
|
||||
if n == nil {
|
||||
return 0
|
||||
}
|
||||
return n.Height
|
||||
}
|
||||
|
||||
func balanceFactor(n *Node) int {
|
||||
if n == nil {
|
||||
return 0
|
||||
}
|
||||
return height(n.Left) - height(n.Right)
|
||||
}
|
||||
|
||||
func updateHeight(n *Node) {
|
||||
l, r := height(n.Left), height(n.Right)
|
||||
if l > r {
|
||||
n.Height = l + 1
|
||||
} else {
|
||||
n.Height = r + 1
|
||||
}
|
||||
}
|
||||
|
||||
// 左旋:右子太重时,把右子 y 提上来,x 沉为 y 的左子
|
||||
//
|
||||
// x y
|
||||
// / \ / \
|
||||
// A y → x C
|
||||
// / \ / \
|
||||
// B C A B
|
||||
//
|
||||
// B 的值在 x、y 之间,必须留在中间 → 挂到 x 的右侧
|
||||
func rotateLeft(x *Node) *Node {
|
||||
y := x.Right
|
||||
x.Right = y.Left
|
||||
y.Left = x
|
||||
updateHeight(x) // 先更新成为孩子的 x
|
||||
updateHeight(y) // 再更新成为根的 y
|
||||
return y
|
||||
}
|
||||
|
||||
// 右旋:左子太重时,把左子 x 提上来,y 沉为 x 的右子
|
||||
//
|
||||
// y x
|
||||
// / \ / \
|
||||
// x C → A y
|
||||
// / \ / \
|
||||
// A B B C
|
||||
//
|
||||
// B 的值在 x、y 之间 → 挂到 y 的左侧
|
||||
func rotateRight(y *Node) *Node {
|
||||
x := y.Left
|
||||
y.Left = x.Right
|
||||
x.Right = y
|
||||
updateHeight(y) // 先更新成为孩子的 y
|
||||
updateHeight(x) // 再更新成为根的 x
|
||||
return x
|
||||
}
|
||||
|
||||
// 插入:递归返回新子树根
|
||||
func Insert(root *Node, val int) *Node {
|
||||
if root == nil {
|
||||
return &Node{Val: val, Height: 1}
|
||||
}
|
||||
if val < root.Val {
|
||||
root.Left = Insert(root.Left, val)
|
||||
} else if val > root.Val {
|
||||
root.Right = Insert(root.Right, val)
|
||||
} else {
|
||||
return root // 不允许重复值
|
||||
}
|
||||
updateHeight(root)
|
||||
bf := balanceFactor(root)
|
||||
|
||||
// LL: 左子左重(左子 BF >= 0)→ 右旋一次
|
||||
if bf > 1 && balanceFactor(root.Left) >= 0 {
|
||||
return rotateRight(root)
|
||||
}
|
||||
// LR: 左子右重(左子 BF < 0)→ 先左旋左子,再右旋自己
|
||||
if bf > 1 && balanceFactor(root.Left) < 0 {
|
||||
root.Left = rotateLeft(root.Left)
|
||||
return rotateRight(root)
|
||||
}
|
||||
// RR: 右子右重(右子 BF <= 0)→ 左旋一次
|
||||
if bf < -1 && balanceFactor(root.Right) <= 0 {
|
||||
return rotateLeft(root)
|
||||
}
|
||||
// RL: 右子左重(右子 BF > 0)→ 先右旋右子,再左旋自己
|
||||
if bf < -1 && balanceFactor(root.Right) > 0 {
|
||||
root.Right = rotateRight(root.Right)
|
||||
return rotateLeft(root)
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
// 删除:递归返回新子树根
|
||||
func Delete(root *Node, val int) *Node {
|
||||
if root == nil {
|
||||
return nil
|
||||
}
|
||||
if val < root.Val {
|
||||
root.Left = Delete(root.Left, val)
|
||||
} else if val > root.Val {
|
||||
root.Right = Delete(root.Right, val)
|
||||
} else {
|
||||
// 命中要删的节点
|
||||
if root.Left == nil {
|
||||
return root.Right
|
||||
}
|
||||
if root.Right == nil {
|
||||
return root.Left
|
||||
}
|
||||
// 两子都在:用右子树最小值替换当前值,再删右子树里的那个最小值
|
||||
minNode := root.Right
|
||||
for minNode.Left != nil {
|
||||
minNode = minNode.Left
|
||||
}
|
||||
root.Val = minNode.Val
|
||||
root.Right = Delete(root.Right, minNode.Val)
|
||||
}
|
||||
updateHeight(root)
|
||||
bf := balanceFactor(root)
|
||||
// 重平衡逻辑与 Insert 完全一致(看子节点 BF 判 case)
|
||||
if bf > 1 && balanceFactor(root.Left) >= 0 {
|
||||
return rotateRight(root)
|
||||
}
|
||||
if bf > 1 && balanceFactor(root.Left) < 0 {
|
||||
root.Left = rotateLeft(root.Left)
|
||||
return rotateRight(root)
|
||||
}
|
||||
if bf < -1 && balanceFactor(root.Right) <= 0 {
|
||||
return rotateLeft(root)
|
||||
}
|
||||
if bf < -1 && balanceFactor(root.Right) > 0 {
|
||||
root.Right = rotateRight(root.Right)
|
||||
return rotateLeft(root)
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
func Search(root *Node, val int) bool {
|
||||
for root != nil {
|
||||
if val < root.Val {
|
||||
root = root.Left
|
||||
} else if val > root.Val {
|
||||
root = root.Right
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 中序遍历 → 应得到升序序列(验证 BST 性质没被破坏)
|
||||
func Inorder(root *Node, out *[]int) {
|
||||
if root == nil {
|
||||
return
|
||||
}
|
||||
Inorder(root.Left, out)
|
||||
*out = append(*out, root.Val)
|
||||
Inorder(root.Right, out)
|
||||
}
|
||||
|
||||
func runAVLDemo() {
|
||||
var root *Node
|
||||
|
||||
// 测试 1: 顺序插入 1..7(普通 BST 会退化成高度=7 的链表)
|
||||
for _, v := range []int{1, 2, 3, 4, 5, 6, 7} {
|
||||
root = Insert(root, v)
|
||||
}
|
||||
var arr []int
|
||||
Inorder(root, &arr)
|
||||
fmt.Println("顺序插入 1..7 中序遍历:", arr)
|
||||
fmt.Printf("树高 = %d (普通BST会=7, AVL 应 ≤ 4)\n", height(root))
|
||||
fmt.Println("Search 5:", Search(root, 5), "Search 99:", Search(root, 99))
|
||||
|
||||
// 测试 2: 乱序插入
|
||||
root = nil
|
||||
for _, v := range []int{5, 2, 8, 1, 9, 3, 7, 6, 4} {
|
||||
root = Insert(root, v)
|
||||
}
|
||||
arr = nil
|
||||
Inorder(root, &arr)
|
||||
fmt.Println("\n乱序插入中序遍历:", arr)
|
||||
fmt.Printf("树高 = %d\n", height(root))
|
||||
|
||||
// 测试 3: 删除
|
||||
root = Delete(root, 5)
|
||||
arr = nil
|
||||
Inorder(root, &arr)
|
||||
fmt.Println("删 5 后中序遍历:", arr)
|
||||
fmt.Println("Search 5:", Search(root, 5))
|
||||
fmt.Printf("树高 = %d\n", height(root))
|
||||
|
||||
// 测试 4: 验证所有 BF ∈ {-1,0,1}
|
||||
if checkAllBF(root) {
|
||||
fmt.Println("\n所有节点 |BF| ≤ 1 ✓")
|
||||
}
|
||||
}
|
||||
|
||||
// 验证整棵树每个节点的 |BF| ≤ 1
|
||||
func checkAllBF(root *Node) bool {
|
||||
var walk func(*Node) bool
|
||||
walk = func(n *Node) bool {
|
||||
if n == nil {
|
||||
return true
|
||||
}
|
||||
bf := balanceFactor(n)
|
||||
if bf < -1 || bf > 1 {
|
||||
fmt.Printf("违反! 节点 %d 的 BF = %d\n", n.Val, bf)
|
||||
return false
|
||||
}
|
||||
return walk(n.Left) && walk(n.Right)
|
||||
}
|
||||
return walk(root)
|
||||
}
|
||||
|
||||
func main() {
|
||||
runAVLDemo()
|
||||
}
|
||||
Reference in New Issue
Block a user