跟我一起学“仓颉”算法-平衡二叉树
·
目录
一、平衡二叉树
平衡二叉树也叫AVL树,它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和左子树的高度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
二、实现
package Algorithm.avl
public class AVLNode {
public var key: Int64
public var height: Int64
public var left: Option<AVLNode>
public var right: Option<AVLNode>
public init(key: Int64) {
this.key = key
this.height = 1
this.left = Option<AVLNode>.None
this.right = Option<AVLNode>.None
}
}
public class AVLTree {
private var root = Option<AVLNode>.None
// 获取节点高度
private func height(node: Option<AVLNode>): Int64 {
if (node.isNone()) {
return 0
} else {
return node.getOrThrow().height
}
}
// 获取平衡因子
private func getBalance(node: Option<AVLNode>): Int64 {
if (node.isNone()) {
return 0
} else {
return height(node.getOrThrow().left) - height(node.getOrThrow().right)
}
}
// 右旋转
private func rightRotate(y: Option<AVLNode>): AVLNode {
var x = y.getOrThrow().left
var T2 = x.getOrThrow().right
// 执行旋转
x.getOrThrow().right = y
y.getOrThrow().left = T2
// 更新高度
y.getOrThrow().height = max(height(y.getOrThrow().left), height(y.getOrThrow().right)) + 1
x.getOrThrow().height = max(height(x.getOrThrow().left), height(x.getOrThrow().right)) + 1
return x.getOrThrow()
}
private func max(a: Int64, b: Int64): Int64 {
if (a > b) {
return a
} else {
return b
}
}
// 左旋转
private func leftRotate(x: Option<AVLNode>): AVLNode {
var y = x.getOrThrow().right
var T2 = y.getOrThrow().left
// 执行旋转
y.getOrThrow().left = x;
x.getOrThrow().right = T2;
// 更新高度
x.getOrThrow().height = max(height(x.getOrThrow().left), height(x.getOrThrow().right)) + 1
y.getOrThrow().height = max(height(y.getOrThrow().left), height(y.getOrThrow().right)) + 1
return y.getOrThrow()
}
// 插入节点
public func insert(key: Int64): Unit {
root = insert(root, key)
}
private func insert(node: Option<AVLNode>, key: Int64): AVLNode {
// 1. 执行标准BST插入
if (node.isNone()) {
return AVLNode(key)
}
if (key < node.getOrThrow().key) {
node.getOrThrow().left = insert(node.getOrThrow().left, key)
} else if (key > node.getOrThrow().key) {
node.getOrThrow().right = insert(node.getOrThrow().right, key)
} else {
return node.getOrThrow() // 不允许重复键
}
// 2. 更新节点高度
node.getOrThrow().height = 1 + max(height(node.getOrThrow().left), height(node.getOrThrow().right))
// 3. 获取平衡因子
var balance = getBalance(node)
// 4. 如果不平衡,有4种情况
// 左左情况
if (balance > 1 && key < node.getOrThrow().left.getOrThrow().key) {
return rightRotate(node.getOrThrow())
}
// 右右情况
if (balance < -1 && key > node.getOrThrow().right.getOrThrow().key) {
return leftRotate(node.getOrThrow())
}
// 左右情况
if (balance > 1 && key > node.getOrThrow().left.getOrThrow().key) {
node.getOrThrow().left = leftRotate(node.getOrThrow().left.getOrThrow())
return rightRotate(node.getOrThrow())
}
// 右左情况
if (balance < -1 && key < node.getOrThrow().right.getOrThrow().key) {
node.getOrThrow().right = rightRotate(node.getOrThrow().right.getOrThrow())
return leftRotate(node.getOrThrow())
}
return node.getOrThrow()
}
// 查找最小值节点
private func minValueNode(node: Option<AVLNode>): AVLNode {
var current = node
while (current.getOrThrow().left.isSome()) {
current = current.getOrThrow().left
}
return current.getOrThrow()
}
// 删除节点
public func delete(key: Int64): Unit {
root = delete(root, key)
}
private func delete(r: Option<AVLNode>, key: Int64): Option<AVLNode> {
var root = r
// 1. 执行标准BST删除
if (root.isNone()) {
return root
}
if (key < root.getOrThrow().key) {
root.getOrThrow().left = delete(root.getOrThrow().left, key)
} else if (key > root.getOrThrow().key) {
root.getOrThrow().right = delete(root.getOrThrow().right, key)
} else {
// 节点有一个子节点或没有子节点
if (root.getOrThrow().left.isNone() || root.getOrThrow().right.isNone()) {
var temp = Option<AVLNode>.None
// 无子节点情况
if (temp.isNone()) {
temp = root
root = Option<AVLNode>.None
} else {
// 有一个子节点情况
root = temp // 复制子节点内容
}
} else {
// 节点有两个子节点,获取中序后继节点(右子树的最小值)
var temp = minValueNode(root.getOrThrow().right)
// 复制中序后继节点的数据
root.getOrThrow().key = temp.key
// 删除中序后继节点
root.getOrThrow().right = delete(root.getOrThrow().right, temp.key)
}
}
// 如果树只有一个节点,直接返回
if (root.isNone()) {
return Option<AVLNode>.None
}
// 2. 更新节点高度
root.getOrThrow().height = max(height(root.getOrThrow().left), height(root.getOrThrow().right)) + 1
// 3. 获取平衡因子
var balance = getBalance(root)
// 4. 如果不平衡,有4种情况
// 左左情况
if (balance > 1 && getBalance(root.getOrThrow().left) >= 0) {
return rightRotate(root.getOrThrow())
}
// 左右情况
if (balance > 1 && getBalance(root.getOrThrow().left) < 0) {
root.getOrThrow().left = leftRotate(root.getOrThrow().left)
return rightRotate(root.getOrThrow())
}
// 右右情况
if (balance < -1 && getBalance(root.getOrThrow().right) <= 0) {
return leftRotate(root)
}
// 右左情况
if (balance < -1 && getBalance(root.getOrThrow().right) > 0) {
root.getOrThrow().right = rightRotate(root.getOrThrow().right)
return leftRotate(root);
}
return root;
}
// 中序遍历
public func inOrder(): Unit {
inOrder(root)
}
private func inOrder(node: Option<AVLNode>): Unit {
if (node.isSome()) {
inOrder(node.getOrThrow().left)
print("${node.getOrThrow().key} ")
inOrder(node.getOrThrow().right)
}
}
// 前序遍历
public func preOrder(): Unit {
preOrder(root)
}
private func preOrder(node: Option<AVLNode>): Unit {
if (node.isSome()) {
print("${node.getOrThrow().key} ")
preOrder(node.getOrThrow().left)
preOrder(node.getOrThrow().right)
}
}
}
测试代码
package Algorithm
import Algorithm.avl.*
main(): Int64 {
let tree = AVLTree()
// 测试插入
tree.insert(10)
tree.insert(20)
tree.insert(30)
tree.insert(40)
tree.insert(50)
tree.insert(25)
println("中序遍历:")
tree.inOrder() // 输出: 10 20 25 30 40 50
println("\n前序遍历:")
tree.preOrder() // 输出: 30 20 10 25 40 50
// 测试删除
tree.delete(50)
println("\n删除50和后的中序遍历:")
tree.inOrder() // 输出: 10 20 25 30 40
return 0
}
三、小结
本章为大家详细的介绍了仓颉数据结构与算法中平衡二叉树的内容,下一章,为大家带来平衡二叉树练习题的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉数据结构与算法有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!
更多推荐


所有评论(0)