当前位置:首页 > JavaScript

js 堆实现

2026-02-01 03:49:52JavaScript

堆(Heap)简介

堆是一种特殊的完全二叉树,分为最大堆(父节点值大于等于子节点)和最小堆(父节点值小于等于子节点)。常用于实现优先队列、堆排序等场景。

js 堆实现

堆的实现关键点

  1. 存储结构:通常用数组表示堆,索引从0或1开始。父子节点关系可通过索引计算:

    js 堆实现

    • 父节点索引:Math.floor((i - 1) / 2)(0-based)
    • 左子节点索引:2 * i + 1
    • 右子节点索引:2 * i + 2
  2. 核心操作

    • 插入(Insert):将新元素添加到末尾,然后向上调整(heapifyUp)。
    • 删除堆顶(Extract):将堆顶与末尾交换,删除末尾,然后向下调整(heapifyDown)。
    • 堆化(Heapify):从最后一个非叶子节点开始向前调整。

JavaScript 最小堆实现代码

class MinHeap {
  constructor() {
    this.heap = [];
  }

  // 获取父节点索引
  getParentIndex(i) {
    return Math.floor((i - 1) / 2);
  }

  // 获取左子节点索引
  getLeftChildIndex(i) {
    return 2 * i + 1;
  }

  // 获取右子节点索引
  getRightChildIndex(i) {
    return 2 * i + 2;
  }

  // 交换元素
  swap(i, j) {
    [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
  }

  // 向上调整
  heapifyUp(index) {
    while (index > 0 && this.heap[index] < this.heap[this.getParentIndex(index)]) {
      const parentIndex = this.getParentIndex(index);
      this.swap(index, parentIndex);
      index = parentIndex;
    }
  }

  // 向下调整
  heapifyDown(index) {
    const leftChildIndex = this.getLeftChildIndex(index);
    const rightChildIndex = this.getRightChildIndex(index);
    let smallest = index;

    if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] < this.heap[smallest]) {
      smallest = leftChildIndex;
    }

    if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] < this.heap[smallest]) {
      smallest = rightChildIndex;
    }

    if (smallest !== index) {
      this.swap(index, smallest);
      this.heapifyDown(smallest);
    }
  }

  // 插入元素
  insert(value) {
    this.heap.push(value);
    this.heapifyUp(this.heap.length - 1);
  }

  // 删除堆顶
  extractMin() {
    if (this.heap.length === 0) return null;
    const min = this.heap[0];
    this.heap[0] = this.heap.pop();
    this.heapifyDown(0);
    return min;
  }

  // 获取堆顶
  peek() {
    return this.heap[0] || null;
  }

  // 构建堆(从无序数组)
  buildHeap(arr) {
    this.heap = [...arr];
    for (let i = Math.floor(this.heap.length / 2) - 1; i >= 0; i--) {
      this.heapifyDown(i);
    }
  }
}

使用示例

const heap = new MinHeap();
heap.insert(3);
heap.insert(1);
heap.insert(4);
console.log(heap.extractMin()); // 输出 1
console.log(heap.peek()); // 输出 3

// 构建堆示例
const heap2 = new MinHeap();
heap2.buildHeap([5, 3, 8, 1, 2]);
console.log(heap2.extractMin()); // 输出 1

时间复杂度

  • 插入(Insert):O(log n)
  • 删除堆顶(Extract):O(log n)
  • 构建堆(BuildHeap):O(n)(通过Floyd算法优化)

标签: js
分享给朋友:

相关文章

js实现轮播

js实现轮播

实现轮播图的基本思路 轮播图的核心逻辑是通过定时切换展示的图片或内容,通常结合左右滑动按钮和指示器(小圆点)增强交互性。以下是基于原生JavaScript的实现方法。 HTML结构 构建轮播图的HT…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现验证

js实现验证

验证表单输入 使用JavaScript验证表单输入是常见的需求。可以通过监听表单提交事件,检查输入字段是否符合要求。 document.getElementById('myForm').addEve…

js 实现vue

js 实现vue

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

js 实现分页

js 实现分页

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

js实现点击显示和隐藏

js实现点击显示和隐藏

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