当前位置:首页 > JavaScript

js实现avl树

2026-01-30 21:49:05JavaScript

AVL树的基本概念

AVL树是一种自平衡二叉搜索树,通过旋转操作保持树的平衡。每个节点的平衡因子(左子树高度减右子树高度)绝对值不超过1。插入或删除节点后,若平衡被破坏,需通过旋转恢复平衡。

节点结构

AVL树的节点需存储值、左右子节点指针和高度。以下为节点类的实现:

class AVLNode {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
    this.height = 1;
  }
}

平衡因子计算

通过左右子树高度差计算平衡因子:

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

节点高度更新

节点高度需动态更新,确保反映子树变化:

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

function updateHeight(node) {
  node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
}

旋转操作

四种旋转操作用于恢复平衡:

js实现avl树

  • 右旋(LL型):处理左子树过深。

    function rightRotate(y) {
    const x = y.left;
    const T2 = x.right;
    
    x.right = y;
    y.left = T2;
    
    updateHeight(y);
    updateHeight(x);
    return x;
    }
  • 左旋(RR型):处理右子树过深。

    function leftRotate(x) {
    const y = x.right;
    const T2 = y.left;
    
    y.left = x;
    x.right = T2;
    
    updateHeight(x);
    updateHeight(y);
    return y;
    }
  • 左右旋(LR型):先左旋后右旋。

    js实现avl树

    function leftRightRotate(node) {
    node.left = leftRotate(node.left);
    return rightRotate(node);
    }
  • 右左旋(RL型):先右旋后左旋。

    function rightLeftRotate(node) {
    node.right = rightRotate(node.right);
    return leftRotate(node);
    }

插入节点

插入节点后检查平衡因子,必要时旋转:

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

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

  updateHeight(node);
  const balanceFactor = getBalanceFactor(node);

  // LL型
  if (balanceFactor > 1 && value < node.left.value) {
    return rightRotate(node);
  }
  // RR型
  if (balanceFactor < -1 && value > node.right.value) {
    return leftRotate(node);
  }
  // LR型
  if (balanceFactor > 1 && value > node.left.value) {
    return leftRightRotate(node);
  }
  // RL型
  if (balanceFactor < -1 && value < node.right.value) {
    return rightLeftRotate(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 = findMin(node.right);
      node.value = temp.value;
      node.right = deleteNode(node.right, temp.value);
    }
  }

  if (!node) return null;

  updateHeight(node);
  const balanceFactor = getBalanceFactor(node);

  // LL型
  if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {
    return rightRotate(node);
  }
  // RR型
  if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) {
    return leftRotate(node);
  }
  // LR型
  if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {
    return leftRightRotate(node);
  }
  // RL型
  if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) {
    return rightLeftRotate(node);
  }

  return node;
}

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

完整示例

以下为AVL树的完整使用示例:

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

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

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

// 使用示例
const tree = new AVLTree();
tree.insert(10);
tree.insert(20);
tree.insert(30); // 自动平衡
tree.delete(20); // 删除后仍保持平衡

注意事项

  • 每次插入或删除后需更新节点高度并检查平衡。
  • 旋转操作需正确处理子树指针,避免断裂。
  • 平衡因子计算需基于当前子树高度,确保准确性。

标签: jsavl
分享给朋友:

相关文章

js实现计算器

js实现计算器

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

js实现验证码

js实现验证码

使用Canvas生成图形验证码 在HTML中创建一个Canvas元素用于绘制验证码。通过JavaScript随机生成数字或字母组合,并添加干扰线、噪点等干扰元素增强安全性。 <canvas i…

js实现打印

js实现打印

使用window.print()方法实现打印 在JavaScript中,可以通过调用window.print()方法直接触发浏览器的打印功能。这会打开系统的打印对话框,用户可以选择打印机和设置打印选项…

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…