当前位置:首页 > JavaScript

js堆实现

2026-04-06 06:56:10JavaScript

JavaScript 堆实现

堆是一种特殊的完全二叉树,分为最大堆和最小堆。最大堆的父节点值大于或等于子节点值,最小堆的父节点值小于或等于子节点值。以下是 JavaScript 中堆的实现方法。

堆的基本结构

堆通常用数组表示,利用数组的索引关系模拟树结构。对于索引 i 的节点:

  • 父节点索引:Math.floor((i - 1) / 2)
  • 左子节点索引:2 * i + 1
  • 右子节点索引:2 * i + 2
class Heap {
  constructor(comparator = (a, b) => a > b) {
    this.heap = [];
    this.comparator = comparator;
  }
}

插入元素

插入元素时,先将元素放到数组末尾,然后通过“上浮”操作调整堆结构。

insert(value) {
  this.heap.push(value);
  this.bubbleUp(this.heap.length - 1);
}

bubbleUp(index) {
  while (index > 0) {
    const parentIndex = Math.floor((index - 1) / 2);
    if (this.comparator(this.heap[index], this.heap[parentIndex])) {
      [this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];
      index = parentIndex;
    } else {
      break;
    }
  }
}

删除堆顶元素

删除堆顶元素时,将堆尾元素移到堆顶,然后通过“下沉”操作调整堆结构。

extract() {
  if (this.heap.length === 0) return null;
  const top = this.heap[0];
  this.heap[0] = this.heap.pop();
  this.sinkDown(0);
  return top;
}

sinkDown(index) {
  const length = this.heap.length;
  while (true) {
    const leftChild = 2 * index + 1;
    const rightChild = 2 * index + 2;
    let swapIndex = null;

    if (leftChild < length && this.comparator(this.heap[leftChild], this.heap[index])) {
      swapIndex = leftChild;
    }
    if (rightChild < length && this.comparator(this.heap[rightChild], this.heap[swapIndex === null ? index : swapIndex])) {
      swapIndex = rightChild;
    }

    if (swapIndex === null) break;
    [this.heap[index], this.heap[swapIndex]] = [this.heap[swapIndex], this.heap[index]];
    index = swapIndex;
  }
}

获取堆顶元素

直接返回数组的第一个元素。

peek() {
  return this.heap.length > 0 ? this.heap[0] : null;
}

堆的大小

返回数组的长度。

size() {
  return this.heap.length;
}

示例用法

以下是一个最大堆的示例用法:

const maxHeap = new Heap();
maxHeap.insert(5);
maxHeap.insert(3);
maxHeap.insert(8);
maxHeap.insert(1);
console.log(maxHeap.extract()); // 8
console.log(maxHeap.extract()); // 5

以下是一个最小堆的示例用法:

js堆实现

const minHeap = new Heap((a, b) => a < b);
minHeap.insert(5);
minHeap.insert(3);
minHeap.insert(8);
minHeap.insert(1);
console.log(minHeap.extract()); // 1
console.log(minHeap.extract()); // 3

时间复杂度

  • 插入操作:O(log n)
  • 删除操作:O(log n)
  • 获取堆顶元素:O(1)
  • 堆的大小:O(1)

通过以上方法,可以在 JavaScript 中实现一个功能完整的堆结构,适用于优先队列、堆排序等场景。

标签: js
分享给朋友:

相关文章

js手势实现

js手势实现

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

js实现图片

js实现图片

图片加载与显示 在JavaScript中,可以通过Image对象动态加载图片。创建实例后设置src属性触发加载,通过onload回调处理加载完成后的操作: const img = new Ima…

js实现搜索

js实现搜索

实现搜索功能的方法 在JavaScript中实现搜索功能可以通过多种方式完成,以下是几种常见的实现方法。 使用数组的filter方法 通过数组的filter方法可以筛选出符合条件的数据项。假设有一个…

js实现下拉刷新

js实现下拉刷新

监听触摸事件 通过监听 touchstart、touchmove 和 touchend 事件来检测用户下拉手势。记录触摸起始位置和移动距离。 let startY = 0; let currentY…

js分页实现

js分页实现

分页的基本原理 分页的核心是通过计算当前页码和数据偏移量,从服务器或本地数据中截取对应范围的数据进行展示。通常需要以下参数:当前页码(currentPage)、每页条数(pageSize)、总数据量(…

js 实现拖拽

js 实现拖拽

实现拖拽的基本步骤 在JavaScript中实现拖拽功能需要监听几个关键事件:mousedown、mousemove和mouseup。以下是实现的基本逻辑。 监听目标元素的mousedown事件,记…