当前位置:首页 > JavaScript

js实现avl树

2026-03-01 12:54:45JavaScript

AVL树简介

AVL树是一种自平衡二叉搜索树,通过旋转操作保持左右子树高度差不超过1。其核心在于维护节点的平衡因子(左子树高度减右子树高度),并在插入或删除时通过四种旋转(左旋、右旋、左右旋、右左旋)恢复平衡。

节点类实现

class AVLNode {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
    this.height = 1; // 初始高度为1
  }
}

平衡因子计算

通过左右子树高度差计算当前节点的平衡因子:

js实现avl树

function getBalanceFactor(node) {
  if (!node) return 0;
  return getHeight(node.left) - getHeight(node.right);
}

function getHeight(node) {
  return node ? node.height : 0;
}

旋转操作

右旋(LL型不平衡)

function rightRotate(y) {
  const x = y.left;
  const T2 = x.right;

  x.right = y;
  y.left = T2;

  y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;
  x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;

  return x; // 返回新的根节点
}

左旋(RR型不平衡)

js实现avl树

function leftRotate(x) {
  const y = x.right;
  const T2 = y.left;

  y.left = x;
  x.right = T2;

  x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
  y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;

  return y;
}

插入节点

插入后递归检查并修复平衡:

function insertNode(node, value) {
  if (!node) return new AVLNode(value);

  if (value < node.value) {
    node.left = insertNode(node.left, value);
  } else if (value > node.value) {
    node.right = insertNode(node.right, value);
  } else {
    return node; // 重复值不插入
  }

  node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));

  const balance = getBalanceFactor(node);

  // LL型
  if (balance > 1 && value < node.left.value) {
    return rightRotate(node);
  }
  // RR型
  if (balance < -1 && value > node.right.value) {
    return leftRotate(node);
  }
  // LR型
  if (balance > 1 && value > node.left.value) {
    node.left = leftRotate(node.left);
    return rightRotate(node);
  }
  // RL型
  if (balance < -1 && value < node.right.value) {
    node.right = rightRotate(node.right);
    return leftRotate(node);
  }

  return node;
}

删除节点

删除后需重新平衡:

function deleteNode(node, value) {
  if (!node) return null;

  if (value < node.value) {
    node.left = deleteNode(node.left, value);
  } else if (value > node.value) {
    node.right = deleteNode(node.right, value);
  } else {
    if (!node.left || !node.right) {
      const temp = node.left || node.right;
      node = temp || null;
    } else {
      const temp = findMinNode(node.right);
      node.value = temp.value;
      node.right = deleteNode(node.right, temp.value);
    }
  }

  if (!node) return null;

  node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));
  const balance = getBalanceFactor(node);

  // 平衡修复逻辑与插入相同
  // ...

  return node;
}

function findMinNode(node) {
  while (node.left) node = node.left;
  return node;
}

完整示例

class AVLTree {
  constructor() {
    this.root = null;
  }

  insert(value) {
    this.root = insertNode(this.root, value);
  }

  delete(value) {
    this.root = deleteNode(this.root, value);
  }
}

复杂度分析

  • 插入/删除:时间复杂度为 O(log n),因每次操作最多需要从叶节点到根节点的路径上执行旋转。
  • 查询:与普通BST相同,为 O(log n)。

标签: jsavl
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 // 方…

js实现计算器

js实现计算器

实现基础计算器功能 使用JavaScript创建一个基础计算器需要处理数字输入、运算符逻辑和结果显示。以下是一个简单的实现示例: let currentInput = '0'; let previo…

js实现图片上传

js实现图片上传

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API可以实现图片上传功能。HTML部分需要创建一个文件选择输入框和一个用于…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js 实现分页

js 实现分页

实现分页的基本逻辑 分页功能通常需要后端返回数据总量或总页数,前端根据当前页码和每页条数截取对应数据。以下是一个基于JavaScript的简单分页实现方案: 前端分页实现 假设已有从后端获取的完整数…

js实现交换

js实现交换

交换变量的方法 在JavaScript中,交换两个变量的值有多种方法。以下是常见的几种实现方式: 使用临时变量 通过引入一个临时变量来存储其中一个变量的值,实现交换: let a = 1; le…