二叉搜索树
添加、删除节点可能导致二叉搜索树退化成链表
那么要如何改进二叉搜索树呢?
节点的添加、删除顺序是无法限制的,也就是随机的。
那么改进方案是:在节点的添加、删除操作之后,想办法让二叉搜索树恢复平衡(减小树的高度)。
如果接着继续调整节点的位置,完全可以达到理想平衡,但是付出的代价可能会比较大。如果调整次数太多,反而增加了时间复杂度。
所以比较合适的方案是:用尽量少的调整次数达到适度平衡。
一颗达到适度平衡的二叉搜索树,可以称之为:平衡二叉搜索树。
平衡二叉搜索树 BBST(Balanced Binary Search Tree)
常见的平衡二叉搜索树
1、AVL树
2、红黑树
一般也称它们为:自平衡的二叉搜索树(Self-balancing Binary Search Tree)
AVL树
平衡因子(Balance Factor):某结点的左右子树的高度差
AVL树的特点:
1、每个节点的平衡因子只可能是 1、0、-1(绝对值 ≤ 1,如果超过 1,称之为“失衡”)
2、每个节点的左右子树高度差不超过1
3、搜索、添加、删除的时间复杂度是 O(logn)
添加导致的失衡
LL– 右旋转(单旋)
RR – 左旋转(单旋)
LR – RR左旋转,LL右旋转(双旋)
RL – LL右旋转,RR左旋转(双旋)
删除导致的失衡
LL– 右旋转(单旋)
RR – 左旋转(单旋)
LR – RR左旋转,LL右旋转(双旋)
RL – LL右旋转,RR左旋转(双旋)
二叉搜索树实现
class BST<T: Comparable>: BinaryTree<T> {
// MARK: 添加
func add(_ element: T) {
if root == nil { // 添加的第一个元素(根结点)
root = createNode(element: element)
size = 1
afterAdd(root!)
return
}
var node = root
var parent = root
var cmp = 0
while node != nil {
parent = node
if element < node!.element {
node = node!.left
cmp = -1
} else if element > node!.element {
node = node!.right
cmp = 1
} else {
node!.element = element
cmp = 0
}
}
let newNode = createNode(element: element, parent: parent)
if cmp > 0 {
parent!.right = newNode
} else {
parent!.left = newNode
}
size += 1
afterAdd(newNode)
}
// MARK: 添加之后调整平衡
func afterAdd(_ node: Node<T>) {
}
// MARK: 删除之后调整平衡
func afterRemove(_ node: Node<T>) {
}
// MARK: 给定结点是否是该二叉树的结点
func contains(_ element: T) -> Bool {
return node(element) != nil
}
// MARK: 删除
func remove(_ element: T) {
remove(node: node(element))
}
private func remove(node: Node<T>?) {
guard var node = node else { return }
size -= 1
if node.hasTwoChildren() {
// 度为2的结点 找到前驱或者后继结点,覆盖原结点的值,再删除前驱或者后继结点
// 如果一个结点的度为2,那么它的前驱或者后继结点的度为0或1
// 找到后继节点
let next = successor(node)
// 用后继节点的值覆盖度为2的节点的值
node.element = next!.element
// 删除后继节点
node = next!
}
// 删除node节点(node的度必然是1或者0)
let replacement = node.left != nil ? node.left : node.right
// 度为1的结点
if replacement != nil {
replacement!.parent = node.parent
if node.parent == nil { // node是度为1的节点并且是根节点
root = replacement
} else if node === node.parent!.left {
node.parent!.left = replacement
} else { // node == node.parent.right
node.parent!.right = replacement
}
// 删除节点之后的处理
afterRemove(node)
} else if node.parent == nil { // node是叶子节点并且是根节点
root = nil
// 删除节点之后的处理
afterRemove(node)
} else { // node是叶子节点,但不是根节点
if node === node.parent!.left {
node.parent!.left = nil
} else { // node == node.parent.right
node.parent!.right = nil
}
// 删除节点之后的处理
afterRemove(node)
}
}
// MARK: 根据结点元素查找结点
private func node(_ element: T) -> Node<T>? {
var node = root
while node != nil {
if node!.element == element {
return node
} else if node!.element > element {
node = node!.left
} else {
node = node!.right
}
}
return nil
}
}
AVL树实现
class AVLTree<T: Comparable>: BST<T> {
override func afterAdd(_ node: BST<T>.Node<T>) {
var n = node.parent
while n != nil {
if isBalanced(n!) {
// 更新高度
updateHeight(n!)
} else {
// 恢复平衡
rebalance(n!)
break
}
n = n!.parent
}
}
override func afterRemove(_ node: BST<T>.Node<T>) {
var n = node.parent
while n != nil {
if isBalanced(n!) {
// 更新高度
updateHeight(n!)
} else {
// 恢复平衡
rebalance(n!)
}
n = n!.parent
}
}
//MARK: 结点是否平衡
private func isBalanced(_ node: Node<T>) -> Bool {
return abs((node as! AVLNode).balanceFactor()) <= 1
}
//MARK: 更新高度
private func updateHeight(_ node: Node<T>) {
(node as! AVLNode).updateHeight()
}
//MARK: 恢复平衡
//MARK: grand 高度最低的那个不平衡结点
private func rebalance(_ grand: Node<T>) {
let parent = (grand as! AVLNode).tallerChild() as! AVLNode
let node = parent.tallerChild() as! AVLNode
if parent.isLeftChild() { // L
if node.isLeftChild() { // LL
rotateRight(grand)
} else { // LR
rotateLeft(parent)
rotateRight(grand)
}
} else { // R
if node.isLeftChild() { // RL
rotateRight(parent)
rotateLeft(grand)
} else { // RR
rotateLeft(grand)
}
}
}
private func rotateLeft(_ grand: Node<T>) {
let parent = grand.right as! AVLNode
let child = parent.left
grand.right = child
parent.left = grand
afterRotate(grand: grand, parent: parent, child: child)
}
private func rotateRight(_ grand: Node<T>) {
let parent = grand.left as! AVLNode
let child = parent.right
grand.left = child
parent.right = grand
afterRotate(grand: grand, parent: parent, child: child)
}
private func afterRotate(grand: Node<T>, parent: Node<T>, child: Node<T>?) {
// 让parent称为子树的根节点
parent.parent = grand.parent
if grand.isLeftChild() {
grand.parent?.left = parent
} else if grand.isRightChild() {
grand.parent?.right = parent
} else {
root = parent
}
// 更新child的parent
child?.parent = grand
// 更新grand的parent
grand.parent = parent
// 更新高度
updateHeight(grand)
updateHeight(parent)
}
override func createNode(element: T, parent: BinaryTree<T>.Node<T>? = nil) -> BinaryTree<T>.Node<T> {
return AVLNode(element: element, parent: parent)
}
private class AVLNode: Node<T> {
var height = 1
// 平衡因子
func balanceFactor() -> Int {
let leftHeight = self.left == nil ? 0 : (self.left as! AVLNode).height
let rightHeight = self.right == nil ? 0 : (self.right as! AVLNode).height
return leftHeight - rightHeight
}
// 更新高度
func updateHeight() {
let leftHeight = self.left == nil ? 0 : (self.left as! AVLNode).height
let rightHeight = self.right == nil ? 0 : (self.right as! AVLNode).height
height = 1 + max(leftHeight, rightHeight)
}
// 高度更高的子结点
func tallerChild() -> Node<T>? {
let leftHeight = self.left == nil ? 0 : (self.left as! AVLNode).height
let rightHeight = self.right == nil ? 0 : (self.right as! AVLNode).height
if leftHeight > rightHeight {
return self.left
}
if leftHeight < rightHeight {
return self.right
}
return isLeftChild() ? self.left : self.right
}
}
}