平衡二叉排序树

162 阅读1分钟

二叉树排序树(二叉搜索树)

  • 左子树都小于根节点值
  • 右子数都大于根节点值
  • 中序遍历为升序排序

操作

100.png

添加

23 -> 10 -> 17 100.png

删除

  • 删除度为0的节点6

101.png

  • 删除度为1的节点10
    将子节点移交给父节点 102.png
  • 💖 删除度为2的节点
    1. 找到当前节点的前驱或者后继节点(中序遍历中的前一个或或一个节点)
    2. 将其与当前节点值互换
    3. 删除前驱节点(转换为删除度为0或1的节点) 103.png
const Node = function(key) {
  this.key = key
  this.left = null
  this.right = null
}

class BinarySortTree {
  constructor() {
    this.root = null
  }

  preDeccessor(node) {
    let temp = node.left
    while(temp.right) temp = temp.right
    return temp
  }

  inorder(node) {
    if (!node) return
    this.inorder(node.left)
    console.log(node.key)
    this.inorder(node.right)
  }

  output() {
    this.inorder(this.root)
  }

  insertNode(root, key) {
    if (!root) {
      const newNode = new Node(key)
      return newNode
    }
    if (root.key === key) return root
    if (root.key > key) root.left = this.insertNode(root.left, key)
    else root.right = this.insertNode(root.right, key)
    return root
  }

  deleteNode(root, key) {
    if (!root) return null
    if (root.key > key) {
      root.left = this.deleteNode(root.left, key)
    } else if (root.key < key) {
      root.right = this.deleteNode(root.right, key)
    } else {
      // 度为0或者度为1
      if (!root.left || !root.right) {
        const child = root.left ? root.left : root.right
        return child
      } else {
        const prev = this.preDeccessor(root)
        root.key = prev.key
        root.left = this.deleteNode(root.left, prev.key)
      }
    }
    return root
  }

  add(key) {
    this.root = this.insertNode(this.root, key)
  }

  delete(key) {
    this.root = this.deleteNode(this.root, key)
  }

}

AVL树

回溯时左右子树不平衡(两者高度差大于1)时,进行调整

🐱‍🐉 实例:5 9 8 3 2 4 1 7

  • 依次插入5,9,8

100.png

  • 5节点处RL型失衡,先拽着9进行小右旋,再拽着5进行大左旋

101.png

  • 依次插入3,2

102.png

  • 5节点处LL型失衡,拽着5进行大右旋

103.png

  • 插入4

105.png

  • 8节点处LR型失衡,拽着3进行小左旋,再拽着8进行大右旋

106.png

  • 依次插入1,7

107.png