返回

构建平衡二叉树,提升查找效率与性能

前端

## 平衡二叉树:计算机科学中的高效搜索利器

在计算机科学的浩瀚世界中,平衡二叉树以其卓越的性能和广泛的应用而著称。它们是高度有序的数据结构,在保持数据井然有序的同时,还提供惊人的查找效率。

平衡二叉树的奥秘

平衡二叉树的精髓在于其巧妙的平衡机制。与普通二叉树不同,平衡二叉树要求其左右子树的高度差不得超过 1。这种限制确保了树的高度始终保持较低,即使在插入或删除元素的情况下。

举个例子,假设我们有一个包含 1000 个元素的平衡二叉树。根据平衡机制,该树的最坏查找复杂度仅为 O(log 1000) ≈ O(10)。这意味着即使数据规模达到 1000 个元素,我们仍然可以快速高效地找到所需数据。

AVL 树:构建平衡二叉树的利器

说到构建平衡二叉树,AVL 树是一种不容忽视的工具。AVL 树是一种自平衡二叉树,能够自动调整其结构以保持平衡。其构建过程虽然涉及一些耐心和细心,但对于掌握平衡二叉树的原理至关重要。

JavaScript 中的平衡二叉树实现

为了更好地理解平衡二叉树的奥妙,我们使用 JavaScript 来实现一个简单的平衡二叉树。这个实现将使用一个类来定义平衡二叉树,并提供一些基本操作,如插入、删除和查找。

// 节点类
class Node {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
    this.height = 1;
  }
}

// AVL 树类
class AVLTree {
  constructor() {
    this.root = null;
  }

  // 插入方法
  insert(value) {
    this.root = this._insert(value, this.root);
  }

  // 插入辅助方法
  _insert(value, node) {
    // 如果节点为空,则创建新节点
    if (node === null) {
      return new Node(value);
    }

    // 根据值大小选择左右子树
    if (value < node.value) {
      node.left = this._insert(value, node.left);
    } else if (value > node.value) {
      node.right = this._insert(value, node.right);
    }

    // 更新节点高度
    node.height = Math.max(this._getHeight(node.left), this._getHeight(node.right)) + 1;

    // 计算平衡因子
    const balanceFactor = this._getBalanceFactor(node);

    // 进行旋转以保持平衡
    if (balanceFactor > 1) {
      // 左旋
      if (value < node.left.value) {
        return this._rightRotate(node);
      } 
      // 右旋
      else {
        node.left = this._leftRotate(node.left);
        return this._rightRotate(node);
      }
    }

    if (balanceFactor < -1) {
      // 右旋
      if (value > node.right.value) {
        return this._leftRotate(node);
      } 
      // 左旋
      else {
        node.right = this._rightRotate(node.right);
        return this._leftRotate(node);
      }
    }

    // 返回更新后的节点
    return node;
  }

  // 获取节点高度的辅助方法
  _getHeight(node) {
    if (node === null) {
      return 0;
    }

    return node.height;
  }

  // 计算平衡因子的辅助方法
  _getBalanceFactor(node) {
    if (node === null) {
      return 0;
    }

    return this._getHeight(node.left) - this._getHeight(node.right);
  }

  // 右旋辅助方法
  _rightRotate(node) {
    const rightChild = node.right;
    node.right = rightChild.left;
    rightChild.left = node;

    // 更新高度
    node.height = Math.max(this._getHeight(node.left), this._getHeight(node.right)) + 1;
    rightChild.height = Math.max(this._getHeight(rightChild.left), this._getHeight(rightChild.right)) + 1;

    // 返回更新后的节点
    return rightChild;
  }

  // 左旋辅助方法
  _leftRotate(node) {
    const leftChild = node.left;
    node.left = leftChild.right;
    leftChild.right = node;

    // 更新高度
    node.height = Math.max(this._getHeight(node.left), this._getHeight(node.right)) + 1;
    leftChild.height = Math.max(this._getHeight(leftChild.left), this._getHeight(leftChild.right)) + 1;

    // 返回更新后的节点
    return leftChild;
  }

  // 查找方法
  search(value) {
    return this._search(value, this.root);
  }

  // 查找辅助方法
  _search(value, node) {
    // 如果节点为空,则返回 null
    if (node === null) {
      return null;
    }

    // 根据值大小选择左右子树
    if (value < node.value) {
      return this._search(value, node.left);
    } else if (value > node.value) {
      return this._search(value, node.right);
    } 

    // 找到节点,返回该节点
    else {
      return node;
    }
  }

  // 删除方法
  delete(value) {
    this.root = this._delete(value, this.root);
  }

  // 删除辅助方法
  _delete(value, node) {
    // 如果节点为空,则返回 null
    if (node === null) {
      return null;
    }

    // 根据值大小选择左右子树
    if (value < node.value) {
      node.left = this._delete(value, node.left);
    } else if (value > node.value) {
      node.right = this._delete(value, node.right);
    } 

    // 找到要删除的节点
    else {
      // 如果节点没有子节点,则直接删除
      if (node.left === null && node.right === null) {
        return null;
      } 
      // 如果节点只有左子节点,则用左子节点替换该节点
      else if (node.left !== null && node.right === null) {
        return node.left;
      } 
      // 如果节点只有右子节点,则用右子节点替换该节点
      else if (node.left === null && node.right !== null) {
        return node.right;
      } 
      // 如果节点既有左子节点又有右子节点,则寻找左子树中的最大节点替换该节点
      else {
        const minNode = this._findMinNode(node.right);
        node.value = minNode.value;
        node.right = this._delete(minNode.value, node.right);
      }
    }

    // 更新节点高度
    node.height = Math.max(this._getHeight(node.left), this._getHeight(node.right)) + 1;

    // 计算平衡因子
    const balanceFactor = this._getBalanceFactor(node);

    // 进行旋转以保持平衡
    if (balanceFactor > 1) {
      // 左旋
      if (this._getBalanceFactor(node.left) >= 0) {
        return this._rightRotate(node);
      } 
      // 右旋
      else {
        node.left = this._leftRotate(node.left);
        return this._rightRotate(node);
      }
    }

    if (balanceFactor < -1) {
      // 右旋
      if (this._getBalanceFactor(node.right) <= 0) {
        return this._leftRotate(node);
      } 
      // 左旋
      else {
        node.right = this._rightRotate(node.right);
        return this._leftRotate(node);
      }
    }

    // 返回更新后的节点
    return node;
  }

  // 查找最小节点的辅助方法
  _findMinNode(node) {
    // 如果节点为空,则返回 null
    if (node === null) {
      return null;
    }

    // 找到左子树中的最小节点
    if (node.left !== null) {
      return this._findMinNode(node.left