go实现平衡二叉树(构建、遍历)
AVL树(自平衡搜索二叉树)的应用场景和特点
AVL 树是一种自平衡二叉搜索树(Self-Balancing Binary Search Tree, SBBST),由 G.M. Adelson-Velsky 和 E.M. Landis 在 1962 年提出。AVL 树的特点是任何节点的两个子树的高度差最多为 1,这保证了树的高度保持在 O(log n),从而确保了查找、插入和删除操作的时间复杂度均为 O(log n)。
特点
-
自平衡:
- AVL 树通过旋转操作来保持平衡。当插入或删除一个节点导致树不平衡时,AVL 树会执行一系列的旋转操作(左旋、右旋、左右旋、右左旋)来恢复平衡。
-
高度平衡:
- 由于每个节点的左右子树高度差不超过 1,AVL 树的高度始终保持在 O(log n),这使得它的操作效率很高。
-
严格的平衡条件:
- 这种严格的平衡条件保证了所有基本操作(如查找、插入、删除)的最坏情况时间复杂度都是 O(log n)。
-
内存开销:
- 每个节点需要额外的空间来存储其高度信息,用于判断是否需要进行平衡操作。
-
插入和删除操作较复杂:
- 相比于普通二叉搜索树,AVL 树的插入和删除操作更复杂,因为需要维护平衡性,这涉及更多的计算和旋转操作。
应用场景
-
数据库索引:
- 在数据库系统中,AVL 树可以用来实现高效的索引结构,特别是在数据量较大且频繁进行查找操作的情况下。
-
实时系统:
- 对于需要快速响应查询的实时系统,AVL 树提供了一种可靠的数据结构选择。
-
符号表:
- 在编译器设计中,AVL 树可以用作符号表,以支持快速的变量查找和更新。
-
集合和映射:
- 在需要高效地管理有序集合或键值对的应用中,AVL 树是一个很好的选择。
-
内存中的数据结构:
- 当需要在内存中维护一个动态的有序集合,并且要求操作具有较高的性能时,AVL 树是一个合适的选择。
总结
AVL 树适合那些需要高效查找、插入和删除操作,并且对数据有序性的应用场景。它通过严格的平衡条件保证了操作的高效性,但同时也带来了更高的实现复杂度。对于需要在数据动态变化的同时保持高效率的应用来说,AVL 树是一个非常强大的工具。然而,在某些情况下,如果不需要如此严格的平衡条件,或者数据集较小,使用其他数据结构(如红黑树)可能更为合适,因为它们在实现上相对简单一些。
代码
package main
import "fmt"
type TreeNode struct {
value int
height int
left *TreeNode
right *TreeNode
}
type AVLTree struct {
root *TreeNode
}
func (n *TreeNode) Height() int {
if n == nil {
return 0
}
return n.height
}
func maxHeight(a *TreeNode, b *TreeNode) int {
if a.Height() > b.Height() {
return a.Height()
}
return b.Height()
}
func computedBalanceFactor(n *TreeNode) int {
return n.left.Height() - n.right.Height()
}
func (tree *AVLTree) Insert(value int) {
tree.root = tree.insert(tree.root, value)
}
func (tree *AVLTree) insert(node *TreeNode, value int) *TreeNode {
if node == nil {
return &TreeNode{value: value, height: 1}
}
if value < node.value {
node.left = tree.insert(node.left, value)
} else if value > node.value {
node.right = tree.insert(node.right, value)
} else {
return node
}
node.height = 1 + maxHeight(node.left, node.right)
balanceFactor := computedBalanceFactor(node)
// 右右
if balanceFactor < -1 && value > node.right.value {
return tree.leftRotate(node)
}
// 左左
if balanceFactor > 1 && value < node.left.value {
return tree.rightRotate(node)
}
// 右左
if balanceFactor < -1 && value < node.right.value {
node.right = tree.rightRotate(node.right)
return tree.leftRotate(node)
}
// 左右
if balanceFactor > 1 && value > node.left.value {
node.left = tree.leftRotate(node.left)
return tree.rightRotate(node)
}
return node
}
func (tree *AVLTree) leftRotate(node *TreeNode) *TreeNode {
y := node.right
T2 := y.left
y.left = node
node.right = T2
node.height = 1 + maxHeight(node.left, node.right)
y.height = 1 + maxHeight(y.left, y.right)
return y
}
func (tree *AVLTree) rightRotate(node *TreeNode) *TreeNode {
x := node.left
T2 := x.right
x.right = node
node.left = T2
node.height = 1 + maxHeight(node.left, node.right)
x.height = 1 + maxHeight(x.left, x.right)
return x
}
func (tree *AVLTree) PrintTree() {
tree.printTree(tree.root, 0)
fmt.Println()
}
func (tree *AVLTree) printTree(node *TreeNode, level int) {
if node != nil {
tree.printTree(node.right, level+1)
fmt.Println()
for i := 0; i < level; i++ {
fmt.Print("\t")
}
fmt.Print(node.value)
tree.printTree(node.left, level+1)
}
}
func (tree *AVLTree) PreOrder() {
tree.preOrder(tree.root)
}
func (tree *AVLTree) preOrder(node *TreeNode) {
if node == nil {
return
}
if node.left != nil {
tree.preOrder(node.left)
}
fmt.Print(node.value, ", ")
if node.right != nil {
tree.preOrder(node.right)
}
}
func main() {
tree := AVLTree{}
values := []int{10, 30, 20, 40, 5, 25}
for _, v := range values {
tree.Insert(v)
}
tree.PrintTree()
// 前序遍历出来的结果是顺序的,参考快速排序
tree.PreOrder()
}
结果
40
30
25
20
10
5
5, 10, 20, 25, 30, 40,

浙公网安备 33010602011771号