当前位置:首页 > JavaScript

js实现avl树

2026-04-04 13:38:35JavaScript

AVL树的实现(JavaScript)

AVL树是一种自平衡二叉搜索树,通过旋转操作保持树的平衡。以下是JavaScript实现的关键步骤和代码示例。

节点类定义

每个节点需要存储值、左右子节点以及高度信息。

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

高度计算与平衡因子

获取节点高度和计算平衡因子(左子树高度减右子树高度)。

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

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

旋转操作

四种旋转情况处理不平衡状态:

  1. 左旋(右右情况)
    
    function leftRotate(node) {
    const newRoot = node.right;
    node.right = newRoot.left;
    newRoot.left = node;

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


2. 右旋(左左情况)
```javascript
function rightRotate(node) {
  const newRoot = node.left;
  node.left = newRoot.right;
  newRoot.right = node;

  node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
  newRoot.height = Math.max(getHeight(newRoot.left), getHeight(newRoot.right)) + 1;
  return newRoot;
}
  1. 左右旋(左右情况)

    function leftRightRotate(node) {
    node.left = leftRotate(node.left);
    return rightRotate(node);
    }
  2. 右左旋(右左情况)

    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; // 不允许重复值
  }

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

  // 左左情况
  if (balance > 1 && value < node.left.value) {
    return rightRotate(node);
  }
  // 右右情况
  if (balance < -1 && value > node.right.value) {
    return leftRotate(node);
  }
  // 左右情况
  if (balance > 1 && value > node.left.value) {
    return leftRightRotate(node);
  }
  // 右左情况
  if (balance < -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 node;

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

  // 平衡调整(与插入相同逻辑)
  if (balance > 1 && getBalanceFactor(node.left) >= 0) {
    return rightRotate(node);
  }
  if (balance > 1 && getBalanceFactor(node.left) < 0) {
    return leftRightRotate(node);
  }
  if (balance < -1 && getBalanceFactor(node.right) <= 0) {
    return leftRotate(node);
  }
  if (balance < -1 && getBalanceFactor(node.right) > 0) {
    return rightLeftRotate(node);
  }

  return node;
}

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

使用示例

let root = null;
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30); // 自动触发左旋
root = deleteNode(root, 20);

复杂度分析

  • 插入/删除操作:O(log n) 时间
  • 旋转操作:O(1) 时间
  • 空间复杂度:O(n) 存储所有节点

实现时需注意边界条件处理,特别是删除操作可能引发多次旋转。可通过中序遍历验证树的正确性:

js实现avl树

function inOrderTraversal(node) {
  if (node) {
    inOrderTraversal(node.left);
    console.log(node.value);
    inOrderTraversal(node.right);
  }
}

标签: jsavl
分享给朋友:

相关文章

js 实现vue

js 实现vue

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

js实现列表

js实现列表

使用 JavaScript 实现列表 JavaScript 提供了多种方式来实现列表功能,包括数组操作、DOM 元素动态生成等。以下是几种常见的实现方法: 使用数组存储列表数据 数组是 JavaSc…

js实现图表

js实现图表

在JavaScript中实现图表通常使用流行的图表库,以下是几种常见的方法和工具: 使用Chart.js Chart.js是一个简单灵活的库,适合快速生成响应式图表。安装方式包括CDN引入或npm安…

js手势实现

js手势实现

手势识别实现方法 在JavaScript中实现手势识别通常涉及监听触摸事件(touchstart、touchmove、touchend)或鼠标事件(mousedown、mousemove、mouseu…

js实现视口

js实现视口

js实现视口检测的方法 使用JavaScript检测元素是否进入视口(viewport)可以通过Intersection Observer API或手动计算元素位置实现。以下是两种常见方法: Int…

js图片上传实现

js图片上传实现

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API实现基础图片上传功能。HTML部分需要设置accept="image/…